package com.cloudkinto.service.order.impl;

import cn.afterturn.easypoi.excel.entity.ExportParams;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.cloudkinto.bo.order.OrderRakutenQueryBo;
import com.cloudkinto.common.DicBusinessItemConstant;
import com.cloudkinto.common.constant.GlobalConstants;
import com.cloudkinto.common.constant.SysConstant;
import com.cloudkinto.common.error.ErrorEnum;
import com.cloudkinto.common.exception.BizException;
import com.cloudkinto.common.exception.BizExceptionI18;
import com.cloudkinto.common.exception.NotSufficientFundsException;
import com.cloudkinto.common.utils.ExcelUtils;
import com.cloudkinto.common.utils.OkHttpUtils;
import com.cloudkinto.common.utils.StringsUtil;
import com.cloudkinto.common.utils.TimeUtils;
import com.cloudkinto.common.utils.dict.StaticDict;
import com.cloudkinto.common.web.PageResult;
import com.cloudkinto.common.web.SingleResult;
import com.cloudkinto.dao.*;
import com.cloudkinto.entity.*;
import com.cloudkinto.service.email.MailSenderService;
import com.cloudkinto.service.finance.CompanyAccountService;
import com.cloudkinto.service.finance.vo.IdAndNameEntity;
import com.cloudkinto.service.operate.OperateRecordService;
import com.cloudkinto.service.operate.vo.OperateRes;
import com.cloudkinto.service.order.OrderRakutenPackageService;
import com.cloudkinto.service.order.OrderRakutenProductService;
import com.cloudkinto.service.order.OrderRakutenService;
import com.cloudkinto.service.order.vo.AutoSwitchStorageEntity;
import com.cloudkinto.service.order.vo.OrderBaseInfoUpdateReq;
import com.cloudkinto.service.order.vo.OrderSenderUpdateReq;
import com.cloudkinto.service.order.vo.rakuten.*;
import com.cloudkinto.service.order.vo.rakuten.importVo.ShipOrderExcelImportVo;
import com.cloudkinto.service.orderoutput.OrderOutputService;
import com.cloudkinto.service.orderoutput.vo.OrderOutputAddReq;
import com.cloudkinto.service.orderoutput.vo.OrderOutputPackageAddReq;
import com.cloudkinto.service.orderoutput.vo.OrderOutputProductAddReq;
import com.cloudkinto.service.product.ProductCombinationService;
import com.cloudkinto.service.product.ProductInfoService;
import com.cloudkinto.service.region.JpRegionService;
import com.cloudkinto.service.shipprice.ShipPriceService;
import com.cloudkinto.service.shop.ShopService;
import com.cloudkinto.service.stock.StockRecordService;
import com.cloudkinto.utils.FreeMarkerUtils;
import lombok.RequiredArgsConstructor;
import org.apache.commons.lang.StringUtils;
import org.apache.poi.ss.usermodel.IndexedColors;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.http.HttpMethod;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;
import org.springframework.web.multipart.MultipartFile;

import javax.mail.Session;
import javax.mail.Transport;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.*;
import java.util.stream.Collectors;

/**
 * <p>
 * service实现类
 * </p>
 *
 * @author 张永远
 * @since 2020-06-03
 */
@Service
@Transactional(rollbackFor = Exception.class)
@RequiredArgsConstructor
public class OrderRakutenServiceImpl extends ServiceImpl<OrderRakutenDao, OrderRakutenDo> implements OrderRakutenService {
    private Logger logger = LoggerFactory.getLogger(getClass());

    @Autowired
    private OrderRakutenDao dao;
    @Autowired
    private OrderRakutenPackageDao packageDao;
    @Autowired
    private OrderRakutenProductDao productDao;
    @Autowired
    private OrderRakutenShippingDao shippingDao;
    @Autowired
    private ShopService mShopService;
    @Autowired
    private OrderRakutenProductService rakutenProductService;
    @Autowired
    private OrderRakutenPackageService rakutenPackageService;

    @Autowired
    private ProductInfoService productInfoService;
    @Autowired
    private ProductSkuMapDao productSkuMapDao;

    @Autowired
    private OrderOutputService outputService;
    @Autowired
    private OperateRecordService operateRecordDao;
    @Autowired
    private CompanyAccountService companyAccountService;
    @Value("${gbc.template.filePath}")
    private String templatePath;
    private int[] orderProgressComm = new int[]{200, 300, 500, 900};
    private int[] orderProgressUnConfirm = new int[]{100};
    private String orderType3 = "3";
    @Autowired
    private ShopDao shopDao;
    @Autowired
    private UserDao userDao;
    @Autowired
    private ShipPriceService shipPriceService;
    @Autowired
    private StorageDao storageDao;
    @Autowired
    private StockRecordDao stockDao;
    //   @Autowired
    private CompanyDao companyDao;
    @Autowired
    private JpRegionService mRegionService;
    @Autowired
    private MailSenderService mailService;
    @Autowired
    private OrderRakutenShippingDao rakutenShippingDao;
    @Autowired
    private ProductCombinationService productCombinationService;
    @Autowired
    private StockRecordService stockRecordService;

    @Override
    public SingleResult addInit() {
        return SingleResult.success("");
    }

    @Override
    public Object add(Object req, Long userId) {
        OrderRakutenDo entityDo = new OrderRakutenDo();
        BeanUtils.copyProperties(req, entityDo);
        handlerAddBefore(entityDo, userId);
        dao.insert(entityDo);
        return handlerAddAfter(entityDo);
    }

    //新增校验
    private void addCheck(Object req) {

    }

    //做新增之前要执行的业务定制处理
    private void handlerAddBefore(OrderRakutenDo entityDo, Long userId) {
//        entityDo.setCreateBy(userId);
//        entityDo.setCreateTime(new Date());
//        entityDo.setDeleteFlag(SysConstant.DELETE_FLAG_FALSE);
    }

    //将新增的do转换成要返回的实体
    private Object handlerAddAfter(OrderRakutenDo entityDo) {
        Object res = new Object();
        BeanUtils.copyProperties(entityDo, res);
        return res;
    }

    @Override
    public SingleResult updateInit(Long id) {
        return SingleResult.success("");
    }

    @Override
    public Object update(Object req, Long userId) {
        /*OrderRakutenDo entityDo = dao.selectById(req.getId());
        BeanUtils.copyProperties(req, entityDo);
        handlerUpdateBefore(entityDo, userId);
        dao.updateById(entityDo);
        return handlerUpdateAfter(entityDo);*/
        return null;
    }

    //编辑校验
    private void updateCheck(Object req) {

    }

    //做修改之前要执行的业务定制处理
    private void handlerUpdateBefore(OrderRakutenDo entityDo, Long userId) {

    }

    //做修改之后要执行的业务定制处理
    private Object handlerUpdateAfter(OrderRakutenDo entityDo) {
        Object res = new Object();
        BeanUtils.copyProperties(entityDo, res);
        return res;
    }

    @Override
    public int delete(Long id, Long userId) {
        OrderRakutenDo entityDo = dao.selectById(id);
        handlerDeleteBefore(entityDo, userId);
        return dao.deleteById(id);
    }

    //做删除之前要执行的业务定制处理
    private void handlerDeleteBefore(OrderRakutenDo entityDo, Long userId) {

    }

    @Override
    public OrderRakutenDetailResponse detail(Long id) {
        OrderRakutenDo entityDo = dao.selectById(id);
        if (entityDo == null) throw new BizExceptionI18(SysConstant.NO_ORDER_INFO);
        OrderRakutenDetailResponse res = new OrderRakutenDetailResponse();
        BeanUtils.copyProperties(entityDo, res);
        return handlerDetailAfter(res);
    }

    @Override
    public OrderRakutenDetailResponse detail(String orderNumber) {
        QueryWrapper wrapper = new QueryWrapper();
        wrapper.eq("order_number", orderNumber);
        OrderRakutenDo entityDo = dao.selectOne(wrapper);
        OrderRakutenDetailResponse res = new OrderRakutenDetailResponse();
        BeanUtils.copyProperties(entityDo, res);
        res.setOrderSubAddres(entityDo.getOrderPrefecture() + entityDo.getOrderCity() + entityDo.getOrderSubAddres());
        return handlerDetailAfter(res);
    }

    //查询明细之后要执行的业务定制处理
    private OrderRakutenDetailResponse handlerDetailAfter(OrderRakutenDetailResponse res) {
        QueryWrapper packageWrapper = new QueryWrapper();
        packageWrapper.eq("order_id", res.getId());
        List<OrderRakutenPackageDo> packageDoList = packageDao.selectList(packageWrapper);
        List<OrderRakutenPackageResponse> packageResponsesList = new ArrayList<>();
        for (OrderRakutenPackageDo packageDo : packageDoList) {
            OrderRakutenPackageResponse packageResponse = new OrderRakutenPackageResponse();
            BeanUtils.copyProperties(packageDo, packageResponse);
            QueryWrapper productWrapper = new QueryWrapper();
            productWrapper.eq("basket_id", packageResponse.getBasketId());
            List<OrderRakutenProductDo> productDoList = productDao.selectList(productWrapper);
            List<OrderRakutenProductResponse> productResponseList = new ArrayList<>();
            packageDao.selectList(packageWrapper);
            for (OrderRakutenProductDo productDo : productDoList) {
                OrderRakutenProductResponse productResponse = new OrderRakutenProductResponse();
                BeanUtils.copyProperties(productDo, productResponse);
                productResponseList.add(productResponse);
            }
            packageResponse.setProductResponseList(productResponseList);
            packageResponsesList.add(packageResponse);
        }
        res.setPackageResponseList(packageResponsesList);

        List<OperateRes> operateRecordDos = operateRecordDao.getOperateList(res.getId(), 5);

        res.setOperateResList(operateRecordDos);

        return res;
    }

    @Override
    public SingleResult pageInit() {
        Map map = new HashMap();
        List<ShopDo> shopDoList = shopDao.selectList(null);
        List<IdAndNameEntity> collect = shopDoList.stream().filter(shopDo -> shopDo.getRakutenSecret() != null).map(shopDo -> {
            return new IdAndNameEntity(shopDo.getId().intValue(), shopDo.getShopName());
        }).collect(Collectors.toList());
        map.put("shopList", collect);
        return SingleResult.success(map);
    }

    /*@Override
    public List<OrderRakutenListRes> getList(Map<String, String> map) {
        QueryWrapper<OrderRakutenDo> wrapper = queryBuild(map);
        List<OrderRakutenDo> list = this.list(wrapper);
        List<OrderRakutenListRes> result = handlerListAfter(list);
        return result;
    }*/

    @Override
    public PageResult getListPage(OrderRakutenQueryBo bo) {
        LambdaQueryWrapper<OrderRakutenDo> wrapper = queryBuild(bo);
        IPage<OrderRakutenDo> page = new Page<>(bo.getCurrent(), bo.getPageSize());
        page = this.page(page, wrapper);
        List<OrderRakutenListRes> resList = handlerListAfter(page.getRecords());
        return new PageResult(resList, (int) page.getCurrent(), (int) page.getSize(), (int) page.getTotal(), (int) page.getPages());
    }

    @Override
    public int orderSync(String dateStart, String dateEnd, String dateType, long shopId) {
        ShopDo shop = verifyShopTokenExist(shopId);
        String[] orderIds = getRakutenOrderIds(dateStart + "T00:00:00+0900", dateEnd + "T23:59:59+0900", dateType, orderProgressComm, shop.getRakutenSecret(), shop.getRakutenLicense());
        getOrder(orderIds, shop);
        return 0;
    }

    private String[] getRakutenOrderIds(String dateStart, String dateEnd, String dateType, int[] orderProgressList, String secret, String license) {
        String authorization = "ESA " + Base64.getEncoder().encodeToString((secret + ":" + license).getBytes());
        String url = GlobalConstants.RakutenURL + "/order/searchOrder/";
//        String url = "http://kintocloud.cn:8080/queryAllShopList";
        JSONObject jsonObject = new JSONObject();
        jsonObject.put("startDatetime", dateStart);
        jsonObject.put("endDatetime", dateEnd);
        jsonObject.put("dateType", dateType);//1,订单创建时间 3订单支付时间
        jsonObject.put("orderProgressList", orderProgressList);
        JSONObject jsonObject1 = new JSONObject();
        jsonObject1.put("requestRecordsAmount", 1000);
        jsonObject1.put("requestPage", 1);
        jsonObject.put("PaginationRequestModel", jsonObject1);
        JSONObject jsonObject2 = new JSONObject();
        jsonObject2.put("userid", 1);
        logger.debug(jsonObject.toJSONString());
        String jsonData = OkHttpUtils.okHttpRequest(url, HttpMethod.POST.name(), jsonObject.toJSONString(), authorization);
        JSONObject object = JSONObject.parseObject(jsonData);
//        logger.debug(object.toJSONString());
        return object.getJSONArray("orderNumberList").toJavaObject(String[].class);
    }


    public String[] searchOrderUnConfirm(String startDate, String endDate, String dateType, String secret, String license) {
        return getRakutenOrderIds(startDate, endDate, dateType, orderProgressUnConfirm, secret, license);
    }

    public void getOrder(String[] orderIds, ShopDo shop) {
        String authorization = "ESA " + Base64.getEncoder().encodeToString((shop.getRakutenSecret() + ":" + shop.getRakutenLicense()).getBytes());
        if (orderIds.length < 1) return;
        String url = GlobalConstants.RakutenURL + "/order/getOrder/";
        for (int i = 0; i <= orderIds.length / 100; i++) {
            String[] orderLimit;
            if (i == orderIds.length / 100) {
                orderLimit = Arrays.copyOfRange(orderIds, i * 100, orderIds.length);
            } else {
                orderLimit = Arrays.asList(orderIds).subList(i * 100, (i + 1) * 100).toArray(new String[100]);
            }
            JSONObject jsonObject = new JSONObject();
            jsonObject.put("orderNumberList", orderLimit);
            logger.debug(jsonObject.toJSONString());
            String jsonData = OkHttpUtils.okHttpRequest(url, HttpMethod.POST.name(), jsonObject.toJSONString(), authorization);
            JSONObject object = JSONObject.parseObject(jsonData);
            List<RakutenOrderModel> orderModels = JSONObject.parseArray(object.getJSONArray("OrderModelList").toJSONString(), RakutenOrderModel.class);
            List<String> confirmOrderIds = new ArrayList<>();
            List<String> queryOrderIds = new ArrayList<>();
            List<RakutenOrderModel> confirmOrders = new ArrayList<>();
            for (RakutenOrderModel orderModel : orderModels) {
                if (orderModel.getOrderProgress() == 100) {
                    if (orderModel.getIsolatedIslandFlag() == 1 && !shop.getAutoConfirmOrderIslandFlag()) {//1是离岛 0是正常
                        continue;
                    }
                    for (RakutenOrderModel.PackageModelListEntity packageModelListEntity : orderModel.getPackageModelList()) {
                        if ((packageModelListEntity.getSenderModel().getPrefecture().contains("北海道") || packageModelListEntity.getSenderModel().getPrefecture().contains("沖縄")) && !shop.getAutoConfirmOrderIslandFlag()) {
                            continue;
                        }
//                        } else {
//                        boolean b = true;
//                            for (RakutenOrderModel.PackageModelListEntity.ItemModelListEntity itemModelListEntity :
//                                    packageModelListEntity.getItemModelList()) {
//                                List<StockRecordBean> recordBeans = mStockDao.queryAllByShopIdAndSku(
//                                        replaceRakutenItemManageNuber(itemModelListEntity.getItemNumber(), itemModelListEntity.getManageNumber())
//                                        , shopId);
//                                if (recordBeans.size() > 0) {
//                                    for (StockRecordBean recordBean : recordBeans) {
//                                        if (recordBean.getCanSell() - recordBean.getSendOutSell() >= itemModelListEntity.getUnits()) {
//                                            b = true;
//                                            break;
//                                        }
//                                    }
//                                }
//                            }
//                        if (b) {
                        confirmOrderIds.add(orderModel.getOrderNumber());
                        confirmOrders.add(orderModel);
//                        }
                    }
                } else {
                    saveRakutenOrder(orderModel, shop.getId(), shop.getCompanyId());
//                    if (orderModel.getOrderProgress() == 300)
//                        queryOrderIds.add(orderModel.getOrderNumber());
                }
            }
//            if (shopId == 4 || shopId == 28)
            if (shop.getAutoConfirmOrderFlag()) {
                confirmRakutenOrder(confirmOrderIds, shop.getRakutenSecret(), shop.getRakutenLicense(), confirmOrders, shop.getId());
            }
            //todo  自动导出到发货单
            if (shop.getAutoSendOutFlag()) {
                queryOrder2SendOut(queryOrderIds.toArray(new String[queryOrderIds.size()]), 135L, true, shop.getCompanyId());
            }
            logger.debug(object.toJSONString());
        }
    }

    private void saveRakutenOrder(RakutenOrderModel orderModel, Long id, Long companyId) {
        OrderRakutenDo rakutenDo = new OrderRakutenDo();
        QueryWrapper wrapper = new QueryWrapper();
        wrapper.eq("order_number", orderModel.getOrderNumber());
        OrderRakutenDo orderRakutenDo = baseMapper.selectOne(wrapper);
        if (orderRakutenDo != null) {
            rakutenDo = orderRakutenDo;
        } else {
            rakutenDo.setCompanyId(companyId);
            rakutenDo.setShopId(id);
        }
        BeanUtils.copyProperties(orderModel, rakutenDo);
        //日期时间格式
        if (rakutenDo.getOrderProgress() == 500 || rakutenDo.getOrderProgress() == 900) {
            rakutenDo.setIsSendOut(1);
        }
        rakutenDo.setOrderDatetime(replaceStrDateFromat(orderModel.getOrderDatetime()));
        rakutenDo.setOrderFixDatetime(replaceStrDateFromat(orderModel.getOrderFixDatetime()));
        rakutenDo.setShopOrderCfmDatetime(replaceStrDateFromat(orderModel.getShopOrderCfmDatetime()));
        rakutenDo.setShippingInstDatetime(replaceStrDateFromat(orderModel.getShippingInstDatetime()));
        rakutenDo.setShippingCmplRptDatetime(replaceStrDateFromat(orderModel.getShippingCmplRptDatetime()));
        rakutenDo.setRequestPrice((orderModel.getRequestPrice().floatValue()));
        if (!org.springframework.util.StringUtils.isEmpty(orderModel.getShippingTerm())) {
            if (orderModel.getShippingTerm().length() > 3) {
                rakutenDo.setShippingTerm(orderModel.getShippingTerm().substring(0, 2) + "-" + orderModel.getShippingTerm().substring(2));
            } else if (orderModel.getShippingTerm().length() > 1) {
                rakutenDo.setShippingTerm(orderModel.getShippingTerm().substring(0, 1) + "-" + orderModel.getShippingTerm().substring(1));
            }
        }
        String tips = orderModel.getRemarks().replaceAll("\\[配送日時指定:\\]", "").replaceAll("\\n", "");
        if (tips.length() > 100) tips = tips.substring(0, 97) + "...";
        rakutenDo.setRemarks(tips);
        rakutenDo.setSystemMemo(orderModel.getMemo());
        //订购人信息
        rakutenDo.setOrderCity(orderModel.getOrdererModel().getCity());
        rakutenDo.setOrderSubAddres(orderModel.getOrdererModel().getSubAddress());
        rakutenDo.setOrderEmailAddress(orderModel.getOrdererModel().getEmailAddress());
        rakutenDo.setOrderPhoneNumber(orderModel.getOrdererModel().getPhoneNumber1() + "-" + orderModel.getOrdererModel().getPhoneNumber2() + "-" + orderModel.getOrdererModel().getPhoneNumber3());
        rakutenDo.setOrderPostCode(orderModel.getOrdererModel().getZipCode1() + "-" + orderModel.getOrdererModel().getZipCode2());
        rakutenDo.setOrderPrefecture(orderModel.getOrdererModel().getPrefecture());
        rakutenDo.setOrderName(orderModel.getOrdererModel().getFamilyName() + " " + orderModel.getOrdererModel().getFirstName());
        rakutenDo.setOrderFamilyNameKana(orderModel.getOrdererModel().getFamilyNameKana());
        rakutenDo.setOrderFirstNameKana(orderModel.getOrdererModel().getFirstNameKana());
        rakutenDo.setOrderBirthday(orderModel.getOrdererModel().getBirthYear() + "-" + orderModel.getOrdererModel().getBirthMonth() + "-" + orderModel.getOrdererModel().getBirthDay());
        rakutenDo.setOrderSex(rakutenDo.getOrderSex());
        //
        if (orderModel.getPointModel() != null) rakutenDo.setUsedPoint(orderModel.getPointModel().getUsedPoint());
        if (orderModel.getDeliveryModel() != null)
            rakutenDo.setDeliveryName(orderModel.getDeliveryModel().getDeliveryName());
        if (orderModel.getCouponModelList() != null && orderModel.getCouponModelList().size() > 0) {
            rakutenDo.setUsedCouponTotalPrice(orderModel.getCouponModelList().get(0).couponTotalPrice);
        }
        saveOrUpdate(rakutenDo);
        for (RakutenOrderModel.PackageModelListEntity packageModelListEntity : orderModel.getPackageModelList()) {
            OrderRakutenPackageDo rakutenPackageInfo = new OrderRakutenPackageDo();
            BeanUtils.copyProperties(packageModelListEntity, rakutenPackageInfo);
            List<OrderRakutenProductDo> rakutenProductInfos = new ArrayList<>();
            StringBuilder sb = new StringBuilder();
            for (RakutenOrderModel.PackageModelListEntity.ItemModelListEntity itemModelListEntity : packageModelListEntity.getItemModelList()) {
                OrderRakutenProductDo productInfo = new OrderRakutenProductDo();
                BeanUtils.copyProperties(itemModelListEntity, productInfo);
                productInfo.setPrice(itemModelListEntity.getPrice());
                if (companyId == 1) {
                    productInfo.setItemNumber(replaceRakutenItemManageNuber(itemModelListEntity.getItemNumber(), itemModelListEntity.getManageNumber()));
                } else {
                    productInfo.setItemNumber(itemModelListEntity.getItemNumber());
                }
                if (itemModelListEntity.getDelvdateInfo() != null) {
                    if (itemModelListEntity.getDelvdateInfo().contains("予約販売")) {
                        rakutenDo.setOrderType(6);
                        rakutenDo.setSystemMemo(itemModelListEntity.getDelvdateInfo());
                    } else if (itemModelListEntity.getDelvdateInfo().contains("あす楽")) {
                        rakutenDo.setAsurakuFlag(1);
                        rakutenDo.setSystemMemo("あす楽" + (rakutenDo.getSystemMemo() == null ? "" : (" " + rakutenDo.getSystemMemo())));
                    }
                }
                productInfo.setBasketId(packageModelListEntity.getBasketId());
                rakutenProductInfos.add(productInfo);
                if (sb.length() > 0) sb.append(",");
                sb.append(productInfo.getItemNumber());
            }
            rakutenDo.setCommoditySku(sb.toString());
            updateById(rakutenDo);
            rakutenProductService.saveOrUpdateProductList(rakutenProductInfos);
            rakutenPackageInfo.setOrderId(rakutenDo.getId());
            //收货人信息
            rakutenPackageInfo.setOrderCity(packageModelListEntity.getSenderModel().getCity());
            rakutenPackageInfo.setOrderSubAddres(packageModelListEntity.getSenderModel().getSubAddress());
//            rakutenPackageInfo.set(packageModelListEntity.getSenderModel().getEmailAddress());
            rakutenPackageInfo.setOrderPhoneNumber(packageModelListEntity.getSenderModel().getPhoneNumber1() + "-" + packageModelListEntity.getSenderModel().getPhoneNumber2() + "-" + packageModelListEntity.getSenderModel().getPhoneNumber3());
            rakutenPackageInfo.setOrderPostCode(packageModelListEntity.getSenderModel().getZipCode1() + "-" + packageModelListEntity.getSenderModel().getZipCode2());
            rakutenPackageInfo.setOrderPrefecture(packageModelListEntity.getSenderModel().getPrefecture());
            rakutenPackageInfo.setOrderName(packageModelListEntity.getSenderModel().getFamilyName() + " " + packageModelListEntity.getSenderModel().getFirstName());
            rakutenPackageInfo.setOrderFamilyNameKana(packageModelListEntity.getSenderModel().getFamilyNameKana());
            rakutenPackageInfo.setOrderFirstNameKana(packageModelListEntity.getSenderModel().getFirstNameKana());
            for (ShippingModelEntity shippingModelEntity : packageModelListEntity.getShippingModelList()) {
                OrderRakutenShippingDo shippingDo = new OrderRakutenShippingDo();
                shippingDo.setPackageId(packageModelListEntity.getBasketId());
                shippingDo.setDeliveryCompany(shippingModelEntity.getDeliveryCompany());
                shippingDo.setDeliveryCompanyName(shippingModelEntity.getDeliveryCompanyName());
                shippingDo.setShippingDate(shippingModelEntity.getShippingDate());
                shippingDo.setShippingDetailId(shippingModelEntity.getShippingDetailId());
                shippingDo.setShippingNumber(shippingModelEntity.getShippingNumber());
                if (rakutenShippingDao.selectById(shippingModelEntity.getShippingDetailId()) == null) {
                    rakutenShippingDao.insert(shippingDo);
                } else {
                    rakutenShippingDao.updateById(shippingDo);
                }
            }
            rakutenPackageService.saveOrUpdatePackage(rakutenPackageInfo);
        }

    }

    private String replaceStrDateFromat(String orderDatetime) {
        if (StringUtils.isEmpty(orderDatetime)) return "";
        return orderDatetime.replace("T", " ").replace("+0900", "");
    }

    private String replaceRakutenItemManageNuber(String itemNumber, String manageNumber) {
        itemNumber = itemNumber.replaceAll("(?i)" + manageNumber, "");
        return itemNumber;
    }

    private void confirmRakutenOrder(List<String> confirmOrderIds, String rakutenSecret, String rakutenLicense, List<RakutenOrderModel> confirmOrders, Long shopId) {
        if (confirmOrderIds.size() < 1) return;
        String authorization = "ESA " + Base64.getEncoder().encodeToString((rakutenSecret + ":" + rakutenLicense).getBytes());
        String url = GlobalConstants.RakutenURL + "/order/confirmOrder/";
//        String url = "http://kintocloud.cn:8080/queryAllShopList";
        JSONObject jsonObject = new JSONObject();
        jsonObject.put("orderNumberList", confirmOrderIds);
        logger.debug(jsonObject.toJSONString());
//        String jsonData = OkHttpUtils.okHttpRequest(url, HttpMethod.POST.name(), jsonObject.toJSONString(), authorization);
//        JSONObject object = JSONObject.parseObject(jsonData);
        //todo 配信   freemaker
        Session session = mailService.initRakutenMailSession();
        Transport transport = null;
//        if (shopId == 4 || shopId == 28) {
//            transport = mailService.initRakutenMailTransport(session);
//        } else if (shopId == 63) {
//            transport = mailService.initRakutenMailTransport(session, "382110", "l1baRYIl7t");
//        } else {
//            transport = mailService.initRakutenMailTransport(session, "377156", "D7TXygKGZ6");
//        }
//        Session session = mailService.initMailSession();
//        Transport transport = mailService.initMailTransport(session);
        for (String orderNumber : confirmOrderIds) {
            QueryWrapper queryWrapper = new QueryWrapper();
            queryWrapper.eq("order_number", orderNumber);
            OrderRakutenDo rakutenDo = dao.selectOne(queryWrapper);
            QueryWrapper packageWrapper = new QueryWrapper();
            packageWrapper.eq("oreder_id", rakutenDo.getId());
            OrderRakutenPackageDo orderRakutenPackageDo = packageDao.selectOne(packageWrapper);
            QueryWrapper productWrapper = new QueryWrapper();
            productWrapper.eq("basket_id", orderRakutenPackageDo.getBasketId());
            List<OrderRakutenProductDo> orderRakutenProductList = productDao.selectList(productWrapper);
            switch (shopId.intValue()) {
//                case 4:
//                    mailService.sendEmailRakuten(session, transport, "【FUTATABI】注文確定のお知らせ",
//                            getConfirmEmailTemplate(rakutenDo, orderRakutenPackageDo, orderRakutenProductList, shopId),
//                            orderModel.getOrdererModel().getEmailAddress()
//                            , "rakuten_service@sanchoum.com", "text/html;charset=Shift-JIS");

//                    break;
//                case 28:
//                    mailService.sendEmailRakuten(session, transport, "【FUTATABI】注文確定のお知らせ",
//                            getConfirmEmailTemplate(rakutenDo, orderRakutenPackageDo, orderRakutenProductList, shopId),
//                            orderModel.getOrdererModel().getEmailAddress()
//                            , "rakuten_service@sanchoum.com", "text/html;charset=Shift-JIS");
//                    break;
//                case 44:
//                    mailService.sendEmailRakuten(session, transport, "【OneTigris Gear楽天市場店】ご注文ありがとうございます！",
//                            getConfirmEmailTemplate(rakutenDo, orderRakutenPackageDo, orderRakutenProductList, shopId),
//                            orderModel.getOrdererModel().getEmailAddress()
//                            , "kuma@onetigris.com", "icey@onetigris.com", "text/html;charset=Shift-JIS");
//                    break;
//                case 63:
//                    mailService.sendEmailRakuten(session, transport, "【YASUYOSHI】注文確定のお知らせ",
//                            getConfirmEmailTemplate(rakutenDo, orderRakutenPackageDo, orderRakutenProductList, shopId),
//                            orderModel.getOrdererModel().getEmailAddress()
//                            , "yasuyoshi@sanchoum.com", "gongbensong@sanchoum.com", "text/html;charset=Shift-JIS");
//                    break;
                default:
//                    mailService.sendEmail(session, transport, String.format("【%s】注文確定のお知らせ", shopDao.selectById(shopId).getShopName()),
//                            getConfirmEmailTemplate(rakutenDo, orderRakutenPackageDo, orderRakutenProductList, shopId),
//                            "770403372@qq.com");
                    break;
            }
//            logger.debug(getConfirmEmailTemplate(rakutenDo, orderRakutenPackageDo, orderRakutenProductList, shopId));

        }
        mailService.transportClose(transport);

    }

    private String getConfirmEmailTemplate(OrderRakutenDo orderModel, OrderRakutenPackageDo orderRakutenPackageDo, List<OrderRakutenProductDo> orderRakutenProductList, Long shopId) {
        try {
            return FreeMarkerUtils.createRakutentConfirmMailTemplate(orderModel, orderRakutenPackageDo, orderRakutenProductList, templatePath + "rakuten_confirm_" + shopId + ".ftl");
        } catch (Exception e) {
            e.printStackTrace();
            logger.error(orderModel.getOrderNumber() + "发信失败");
            //todo 写入异常日志通知顾客
        }
        return "";
    }

    private String getSendOutEmailTemplate(OrderRakutenDo orderModel, OrderRakutenPackageDo orderRakutenPackageDo, List<OrderRakutenProductDo> orderRakutenProductList, ShippingModelEntity shippingModelEntity, Long shopId) {
        try {
            return FreeMarkerUtils.createRakutenSendOutMailTemplate(orderModel, orderRakutenPackageDo, orderRakutenProductList, shippingModelEntity, templatePath + "rakuten_sendout_" + shopId + ".ftl");
        } catch (Exception e) {
            e.printStackTrace();
            logger.error(orderModel.getOrderNumber() + "发信失败");
            //todo 写入异常日志通知顾客
        }
        return "";
    }

    /**
     * @param shippingModelRequests
     * @param shopId
     * @param secret
     * @param license
     */
    @Override
    public void updateOrderShipping(List<OrderShippingModelRequest> shippingModelRequests, Long shopId, String secret, String license) {
        String authorization = "ESA " + Base64.getEncoder().encodeToString((secret + ":" + license).getBytes());
        logger.debug(authorization);
        String url = GlobalConstants.RakutenURL + "/order/updateOrderShippingAsync/";
        JSONObject order = new JSONObject();
        order.put("OrderShippingModelList", shippingModelRequests);
        logger.debug(order.toJSONString());
        String jsonData = OkHttpUtils.okHttpRequest(url, HttpMethod.POST.name(), order.toJSONString(), authorization);
        JSONObject object = JSONObject.parseObject(jsonData);
        try {
            if ("ORDER_EXT_API_UPDATE_ORDERSHIPPING_ASYNC_INFO_101".equals(object.getJSONArray("MessageModelList").getJSONObject(0).getString("messageCode"))) {


            } else {
                //todo 处理上传运单号失败的情况
                return;
            }
            logger.debug(object.getJSONArray("MessageModelList").toString());
        } catch (Exception e) {
            e.printStackTrace();
            return;
        }
        Session session = mailService.initRakutenMailSession();
        Transport transport = null;
        if (shopId == 4) {
            transport = mailService.initRakutenMailTransport(session);
        } else if (shopId == 28) {
            transport = mailService.initRakutenMailTransport(session, "382120", "1kNt34Tydu");
        } else if (shopId == 63) {
            transport = mailService.initRakutenMailTransport(session, "382110", "l1baRYIl7t");
        } else {
            transport = mailService.initRakutenMailTransport(session, "377156", "D7TXygKGZ6");
        }
//        Session session = mailService.initMailSession();
//        Transport transport = mailService.initMailTransport(session);
        for (OrderShippingModelRequest request : shippingModelRequests) {
            QueryWrapper queryWrapper = new QueryWrapper();
            queryWrapper.eq("order_number", request.getOrderNumber());
            OrderRakutenDo rakutenDo = dao.selectOne(queryWrapper);
            updateRakutenOrderSendOut(request.getOrderNumber());
            if (rakutenDo.getIsSendMail() == 1) {
                continue;
            }
            try {
                Thread.sleep(8 * 1000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            //todo 配信   freemaker
            QueryWrapper packageWrapper = new QueryWrapper();
            packageWrapper.eq("order_id", rakutenDo.getId());
            List<OrderRakutenPackageDo> orderRakutenPackageDoList = packageDao.selectList(packageWrapper);
            for (int i = 0; i < orderRakutenPackageDoList.size(); i++) {
                OrderRakutenPackageDo orderRakutenPackageDo = orderRakutenPackageDoList.get(i);
                QueryWrapper productWrapper = new QueryWrapper();
                productWrapper.eq("basket_id", orderRakutenPackageDo.getBasketId());
                List<OrderRakutenProductDo> orderRakutenProductList = productDao.selectList(productWrapper);
                switch (rakutenDo.getShopId().intValue()) {
                    case 4:
                        mailService.sendEmailRakuten(session, transport, "【MWPO】商品発送完了のお知らせ", getSendOutEmailTemplate(rakutenDo, orderRakutenPackageDo, orderRakutenProductList, request.getBasketidModelList().get(0).getShippingModelList().get(0), shopId), rakutenDo.getOrderEmailAddress(), "rakuten_service@sanchoum.com", "text/html;charset=Shift-JIS");
                        break;
                    case 28:
                        mailService.sendEmailRakuten(session, transport, "【FUTATABI】商品発送完了のお知らせ", getSendOutEmailTemplate(rakutenDo, orderRakutenPackageDo, orderRakutenProductList, request.getBasketidModelList().get(0).getShippingModelList().get(0), shopId), rakutenDo.getOrderEmailAddress(), "futatabi@sanchoum.com", "futatabi@sanchoum.com", "text/html;charset=Shift-JIS");
                        break;
                    case 44:
                        mailService.sendEmailRakuten(session, transport, "【OneTigris Gear楽天市場店】商品発送完了のお知らせ", getSendOutEmailTemplate(rakutenDo, orderRakutenPackageDo, orderRakutenProductList, request.getBasketidModelList().get(0).getShippingModelList().get(0), shopId), rakutenDo.getOrderEmailAddress(), "kuma@onetigris.com", "icey@onetigris.com", "text/html;charset=Shift-JIS");
                        break;
                    case 63:
                        mailService.sendEmailRakuten(session, transport, "【YASUYOSHI】商品発送完了のお知らせ", getSendOutEmailTemplate(rakutenDo, orderRakutenPackageDo, orderRakutenProductList, request.getBasketidModelList().get(0).getShippingModelList().get(0), shopId), rakutenDo.getOrderEmailAddress(), "yasuyoshi@sanchoum.com", "gongbensong@sanchoum.com", "text/html;charset=Shift-JIS");
                        break;
                    default:
//                    mailService.sendEmail(session, transport, String.format("【%s】商品発送完了のお知らせ", shopDao.selectById(shopId).getShopName()),
//                            getSendOutEmailTemplate(rakutenDo, orderRakutenPackageDo, orderRakutenProductList,
//                                    request.getBasketidModelList().get(0).getShippingModelList().get(0), shopId),
//                            "770403372@qq.com");
                        break;
                }
            }
//            logger.debug(getSendOutEmailTemplate(rakutenDo, orderRakutenPackageDo, orderRakutenProductList,
//                    request.getBasketidModelList().get(0).getShippingModelList().get(0), shopId));
            updateRakutenOrderSendMail(request.getOrderNumber());
        }
        mailService.transportClose(transport);
    }

    private void updateRakutenOrderSendOut(String orderNumber) {
        UpdateWrapper wrapper = new UpdateWrapper();
        wrapper.eq("order_number", orderNumber);
        wrapper.set("is_upload_express", 1);
        update(wrapper);

    }

    private void updateRakutenOrderSendMail(String orderNumber) {
        UpdateWrapper wrapper = new UpdateWrapper();
        wrapper.eq("order_number", orderNumber);
        wrapper.set("is_upload_express", 1);
        update(wrapper);

    }


    @Override
    public void exportExcel(OrderRakutenQueryBo bo, HttpServletResponse response) throws IOException {
        List<OrderRakutenDo> orderRakutenDoList;
        if (CollectionUtils.isEmpty(bo.getIds())) {
            orderRakutenDoList = this.baseMapper.selectList(queryBuild(bo));
        } else {
            orderRakutenDoList = this.baseMapper.selectList(
                    Wrappers.<OrderRakutenDo>lambdaQuery()
                            .in(OrderRakutenDo::getId, bo.getIds())
                            .eq(Objects.nonNull(bo.getCompanyId()), OrderRakutenDo::getCompanyId, bo.getCompanyId())
                            .orderByDesc(OrderRakutenDo::getOrderFixDatetime)
            );
        }


        if (orderRakutenDoList.size() > 1000) {
            response.setStatus(500);
            throw new BizExceptionI18(SysConstant.Order_Count_Oversize_1000);
        }
        List<OrderRakutenExcelExportVo> excelExportVoList = new ArrayList<>();

        if (!CollectionUtils.isEmpty(orderRakutenDoList)) {
            for (OrderRakutenDo rakutenDo : orderRakutenDoList) {
                OrderRakutenExcelExportVo excelExportVo = new OrderRakutenExcelExportVo();
                BeanUtils.copyProperties(rakutenDo, excelExportVo);

                LambdaQueryWrapper<OrderRakutenPackageDo> packageDoLambdaQueryWrapper = new LambdaQueryWrapper<>();
                packageDoLambdaQueryWrapper.eq(OrderRakutenPackageDo::getOrderId, rakutenDo.getId());
                List<OrderRakutenPackageDo> packageDoList = packageDao.selectList(packageDoLambdaQueryWrapper);
                if (!CollectionUtils.isEmpty(packageDoList)) {
                    for (OrderRakutenPackageDo packageDo : packageDoList) {
                        excelExportVo.setShipPostCode(packageDo.getOrderPostCode());
                        excelExportVo.setShipPhoneNumber(packageDo.getOrderPhoneNumber());
                        excelExportVo.setShipPrefecture(packageDo.getOrderPrefecture());
                        excelExportVo.setShipSubAddres(packageDo.getOrderSubAddres());
                        excelExportVo.setShipName(packageDo.getOrderName());
                        excelExportVo.setOrderSubAddres(packageDo.getOrderCity() + packageDo.getOrderSubAddres());
                        LambdaQueryWrapper<OrderRakutenProductDo> productDoLambdaQueryWrapper = new LambdaQueryWrapper<>();
                        productDoLambdaQueryWrapper.eq(OrderRakutenProductDo::getBasketId, packageDo.getBasketId());
                        List<OrderRakutenProductDo> productDoList = productDao.selectList(productDoLambdaQueryWrapper);
                        if (!CollectionUtils.isEmpty(productDoList)) {
                            List<OrderRakutenProductExcelExportVo> productExcelExportVoList = new ArrayList<>();
                            for (OrderRakutenProductDo productDo : productDoList) {
                                OrderRakutenProductExcelExportVo productExcelExportVo = new OrderRakutenProductExcelExportVo();
                                BeanUtils.copyProperties(productDo, productExcelExportVo);
                                productExcelExportVoList.add(productExcelExportVo);
                            }
                            excelExportVo.setPackageExcelExportVoList(productExcelExportVoList);
                        }
                    }
                }
                excelExportVoList.add(excelExportVo);
            }
        }
        ExportParams exportParams = new ExportParams();
        exportParams.setCreateHeadRows(true);
        exportParams.setHeaderColor(IndexedColors.YELLOW.getIndex());
        ExcelUtils.exportExcel(excelExportVoList, OrderRakutenExcelExportVo.class, "乐天订单", exportParams, response);
    }

    /**
     * 验证该店铺是否有APItoken
     *
     * @param shopId
     * @return
     */
    private ShopDo verifyShopTokenExist(long shopId) {
        ShopDo shopBean = mShopService.getShopTokenById(shopId);
        if (StringUtils.isEmpty(shopBean.getRakutenLicense()) || StringUtils.isEmpty(shopBean.getRakutenSecret())) {
            throw new BizExceptionI18(SysConstant.SHOP_NO_TOKEN);
        }
        return shopBean;
    }


    @Override
    public SingleResult export2ShipOrderExcel(MultipartFile file, Long userId, Long companyId) {
        List<ShipOrderExcelImportVo> excelImportList = new ArrayList<>();
        String suffix = file.getOriginalFilename().substring(file.getOriginalFilename().lastIndexOf(".") + 1);
        if (!GlobalConstants.IMG_TYPE_XLS.equals(suffix.toUpperCase()) && !GlobalConstants.IMG_TYPE_XLSX.equals(suffix.toUpperCase())) {
            throw new BizException(SysConstant.File_Form_Incorrect);
        }
        try {
            excelImportList = ExcelUtils.importExcel(file, 0, 1, ShipOrderExcelImportVo.class);
        } catch (IOException e) {
            e.printStackTrace();
        }
        if (excelImportList == null || excelImportList.size() == 0) {
            throw new BizException(SysConstant.No_Data);
        }
        List<OrderRakutenDo> list = dao.selectList(new LambdaQueryWrapper<OrderRakutenDo>().in(OrderRakutenDo::getOrderNumber, excelImportList.stream().map(ShipOrderExcelImportVo::getOrderNo).collect(Collectors.toList())).eq(OrderRakutenDo::getCompanyId, companyId));
        if (list.size() == 0) {
            throw new BizException(SysConstant.No_Data);
        }
        String[] orderIds = new String[list.size()];
        for (int i = 0; i < list.size(); i++) {
            orderIds[i] = list.get(i).getId() + "";
        }
        return this.queryOrder2SendOut(orderIds, userId, false, companyId);
    }


    /**
     * 转到发货单
     *
     * @param orderids
     * @param currentUserId
     * @param isAuto
     * @return
     */
    @Override
    public SingleResult queryOrder2SendOut(String[] orderids, Long currentUserId, boolean isAuto, Long companyId) {
        if (orderids.length == 0) {
            throw new BizException(SysConstant.Error_PleChoose);
        }
        //校验余额是否不足
        sufficientFundsCheck(companyId);
        List<OrderRakutenDo> orderRakutenDos = dao.selectList(new LambdaQueryWrapper<OrderRakutenDo>().in(OrderRakutenDo::getId, Arrays.asList(orderids))
                .orderByAsc(OrderRakutenDo::getOrderFixDatetime));
        List<String> failOrders = new ArrayList<>();
        List<OrderOutputAddReq> orderOutputAddReqList = new ArrayList<>();
        for (OrderRakutenDo et : orderRakutenDos) {
            List<OrderOutputAddReq> outputAddReqs = new ArrayList<>();
            try {
                outputAddReqs = sendOutOrder(et, isAuto);
            } catch (BizException e) {
                e.printStackTrace();
                failOrders.add(StringsUtil.createI18Message(e.getMessage(), e.getArgs()));
            }
            if (outputAddReqs.size() < 1) continue;
            orderOutputAddReqList.addAll(outputAddReqs);
//            Session session = mailService.initMailSession();
//            Transport transport = mailService.initMailTransport(session);
//             operateRecordDao.operateAddRecord(SysConstant.OPERATE_CLICK_SEND, et.getId(), currentUserId, 5);
//            operateRecord("点击发货", Long.parseLong(orderid), currentUserId);
        }
//        List<String> failOrders = new ArrayList<>();
        if (isAuto) {
            sendOutMatch(orderOutputAddReqList, currentUserId, companyId);
        }
        for (OrderOutputAddReq outputAddReq : orderOutputAddReqList) {
            StringBuilder sku = new StringBuilder();
            int cout = 0;
            for (OrderOutputProductAddReq orderOutputProductAddReq : outputAddReq.getPackageList().get(0).getProductList()) {
                cout = cout + orderOutputProductAddReq.getCount();
                if (org.apache.commons.lang3.StringUtils.isNotBlank(sku)) {
                    sku.append(",");
                }
                sku.append(productInfoService.getById(orderOutputProductAddReq.getProductId()).getCommoditySku());
            }
            outputAddReq.setSku(sku.toString());
            outputAddReq.setCount(cout);
        }
        Map map = new HashMap();
        map.put("orderList", orderOutputAddReqList);
        map.put("failedList", failOrders);
        map.put("storageList", storageDao.selectList(null));
        return SingleResult.success(map);
    }

    @Override
    public SingleResult queryOrder2SendOutNoPackage(String orderid, Long currentUserId, boolean b, Long companyId) {
        //校验余额是否不足
        sufficientFundsCheck(companyId);
        List<String> failOrders = new ArrayList<>();
        List<OrderOutputAddReq> orderOutputAddReqList = new ArrayList<>();
        try {
            OrderRakutenDo rakutenDo = this.baseMapper.selectById(orderid);
            if (rakutenDo == null) throw new BizExceptionI18(SysConstant.NO_ORDER_INFO_ID);
            if (rakutenDo.getOrderProgress() < 300 && StringUtils.isBlank(rakutenDo.getOrderFixDatetime()))
                throw new BizExceptionI18(SysConstant.ORDER_NO_PAYMENT_ID, rakutenDo.getOrderNumber());
            if (rakutenDo.getOrderProgress() == 900)
                throw new BizExceptionI18(SysConstant.ORDER_HAS_CANCEL_ID, rakutenDo.getOrderNumber());
            //订单
            OrderOutputAddReq res = new OrderOutputAddReq();
            res.setOrderType(1);
            res.setPlatform("rakuten");

            res.setPlatformNumber(rakutenDo.getId() + "");
            res.setSendDate(new Date());
            res.setShopId(rakutenDo.getShopId());
            res.setCompanyId(rakutenDo.getCompanyId());
            res.setOrderNo(rakutenDo.getOrderNumber());
            res.setTips(rakutenDo.getRemarks());

            res.setDeliveryDate(rakutenDo.getDeliveryDate());
            if ("1".equals(rakutenDo.getShippingTerm())) {
                res.setDeliveryTime("09-12");
            } else {
                res.setDeliveryTime(rakutenDo.getShippingTerm());
            }
            res.setShipmentType(rakutenDo.getAsurakuFlag());//乐天次日达
            QueryWrapper<OrderRakutenPackageDo> wrapper = new QueryWrapper<>();
            wrapper.eq("order_id", orderid);
            List<OrderRakutenPackageDo> packageDoList = packageDao.selectList(wrapper);
            if (packageDoList == null || packageDoList.size() < 1)
                throw new BizExceptionI18(SysConstant.ORDER_NO_SKU_ID, rakutenDo.getOrderNumber());
            if (rakutenDo.getSomeSenderFlag() == null || rakutenDo.getSomeSenderFlag() == 0) {
                OrderRakutenPackageDo packageDo = packageDoList.get(0);//乐天默认一个包裹
                res.setReceiverName(packageDo.getOrderName());
                if (packageDo.getOrderPrefecture() != null && packageDo.getOrderPrefecture().equals("国外")) {
                    throw new BizExceptionI18(SysConstant.ORDER_NO_ADDRESS_INFO2, rakutenDo.getOrderNumber(), packageDo.getOrderPrefecture());
                }
                res.setTelPhone(packageDo.getOrderPhoneNumber());
                res.setPostCode(packageDo.getOrderPostCode());
                res.setArea(packageDo.getOrderPrefecture());
                res.setAddress(packageDo.getOrderCity() + packageDo.getOrderSubAddres());
                res.setCod(res.getCod());
                if (rakutenDo.getCompanyId() == 221) {
                    QueryWrapper<OrderRakutenShippingDo> shippingDoQueryWrapper = new QueryWrapper<>();
                    shippingDoQueryWrapper.eq("package_id", packageDo.getBasketId());
                    List<OrderRakutenShippingDo> shippingDoList = shippingDao.selectList(shippingDoQueryWrapper);
                    long count = shippingDoList.stream().filter(orderRakutenShippingDo -> orderRakutenShippingDo.getDeliveryCompany().equals("1004")).count();
                    if (count > 0) res.setTrackId(DicBusinessItemConstant.xinongExpress);
                }
                QueryWrapper<OrderRakutenProductDo> productDoQueryWrapper = new QueryWrapper<>();
                productDoQueryWrapper.eq("basket_id", packageDo.getBasketId());
                List<OrderOutputProductAddReq> productAddList = new ArrayList<>();
                //得到乐天订单的产品信息集合
                List<OrderRakutenProductDo> productDoList = productDao.selectList(productDoQueryWrapper);
                List<OrderOutputProductAddReq> productDoList1 = new ArrayList<>();
                if (productDoList == null || productDoList.size() < 1)
                    throw new BizExceptionI18(SysConstant.ORDER_NO_SKU_ID, rakutenDo.getOrderNumber());
                for (OrderRakutenProductDo productDo : productDoList) {
                    if (productDo.getItemNumber().contains("+")) {
                        for (String sku : productDo.getItemNumber().split("\\+")) {
                            OrderOutputProductAddReq productDo1 = new OrderOutputProductAddReq();
                            productDo1.setProductId(productInfoService.getProductId(sku, rakutenDo.getCompanyId()));
                            productDo1.setCommoditySku(sku);
                            productDo1.setCount(productDo.getUnits());
                            productDoList1.add(productDo1);
                        }
                    } else {
                        ProductInfoDo productInfoDo = productInfoService.getProductDo(productDo.getItemNumber(), rakutenDo.getCompanyId());
                        if (productInfoDo == null) {
                            failOrders.add(StringsUtil.createI18Message(SysConstant.ORDER_NO_SKU_INFO2_ID, rakutenDo.getOrderNumber(), productDo.getItemNumber()));
                            continue;
                        }
                        if (!productInfoDo.getTypeOfProduct().equals(StaticDict.Product_Info_Type.Combination.getValue())) {
                            OrderOutputProductAddReq productDo1 = new OrderOutputProductAddReq();
                            productDo1.setProductId(productInfoDo.getId());
                            productDo1.setCommoditySku(productInfoDo.getCommoditySku());
                            productDo1.setCount(productDo.getUnits());
                            productDoList1.add(productDo1);
                        } else {
                            LambdaQueryWrapper<ProductCombinationDo> productCombinationWrapper = new LambdaQueryWrapper<>();
                            productCombinationWrapper.eq(ProductCombinationDo::getParentId, productInfoDo.getId());
                            List<ProductCombinationDo> productCombinationDoList = productCombinationService.getBaseMapper().selectList(productCombinationWrapper);
                            for (ProductCombinationDo productCombinationDo : productCombinationDoList) {
                                if (productCombinationDo.getEffective() == 1) {
                                    Date date = TimeUtils.parseDate(rakutenDo.getOrderDatetime(), "yyyy-MM-dd HH:mm:ss");
                                    if (productCombinationDo.getEffectBeginTime() == null || productCombinationDo.getEffectEndTime() == null)
                                        continue;
                                    if (date.getTime() < productCombinationDo.getEffectBeginTime().getTime()
                                            || date.getTime() > productCombinationDo.getEffectEndTime().getTime())
                                        continue;
                                }
                                OrderOutputProductAddReq productDo1 = new OrderOutputProductAddReq();
                                ProductInfoDo productInfoDo1 = productInfoService.getById(productCombinationDo.getChildId());
                                if (productInfoDo1 == null) {
                                    failOrders.add(StringsUtil.createI18Message(SysConstant.ORDER_NO_SKU_GROUP_INFO_ID, rakutenDo.getOrderNumber(), productDo.getItemNumber()));
                                    continue;
                                }
                                productDo1.setProductId(productCombinationDo.getChildId());
                                productDo1.setCommoditySku(productInfoDo1.getCommoditySku());
                                productDo1.setCount(productDo.getUnits() * productCombinationDo.getCount());
                                productDoList1.add(productDo1);
                            }
                        }
                    }
                }
//                productDoList.clear();
//                productDoList.addAll(productDoList1);
                int orderCount = 0;
                for (OrderOutputProductAddReq productDo : productDoList1) {
                    double[] size = new double[4];
                    long storageId = 0L;
                    double shipPirce = 99999D;
                    List<OrderOutputAddReq> resList = new ArrayList<>();
                    List<StorageDo> storageDoList = storageDao.selectList(null);
                    Long productId = null;
                    try {
                        productId = productDo.getProductId();
                    } catch (BizException e) {
                        e.printStackTrace();
                        failOrders.add(StringsUtil.createI18Message(e.getMessage(), e.getArgs()));
                        continue;
                    }
                    for (StorageDo storageDo : storageDoList) {//遍历仓库是否都有库存
                        LambdaQueryWrapper<StockRecordDo> wrapper2 = new LambdaQueryWrapper();
                        size = shipPriceService.countSameSkuSize(new double[4], productId, 1);
                        // wrapper2.eq(StockRecordDo::getShopId, rakutenDo.getShopId()).eq(StockRecordDo::getProductInfoId, productId).eq(StockRecordDo::getStorageId, storageDo.getId());
                        // StockRecordDo stockRecordDo1 = stockDao.selectOne(wrapper2);
                        // int noDeliveredCount1 = stockDao.getOrderOutCount(productId, rakutenDo.getShopId(), storageDo.getId());
                        int canUseCount = stockRecordService.getStockCount(rakutenDo.getCompanyId(), rakutenDo.getShopId(), storageDo.getId(), productId, productDo.getCount());
                        if (canUseCount > 0) {
                            List<ShipPriceDo> shipPriceDos = shipPriceService.queryByRegionAndSize(packageDo.getOrderPostCode(), size, res.getCod(), res.getShipmentType(), storageDo.getId(), 1, res.getCompanyId());
                            if (shipPriceDos.size() < 1 || shipPriceDos.get(0).getPrice() == 0) continue;
                            if (shipPirce > shipPriceDos.get(0).getPrice()) {//选择最便宜的价格
                                shipPirce = shipPriceDos.get(0).getPrice();
                                storageId = storageDo.getId();
                            }
                        }
                    }
                    OrderOutputProductAddReq productDetail = new OrderOutputProductAddReq();
                    productDetail.setProductId(productId);
                    productDetail.setCount(productDo.getCount());
                    productAddList = new ArrayList<>();
                    productAddList.add(productDetail);
                    OrderOutputPackageAddReq packageDetail = new OrderOutputPackageAddReq();
                    packageDetail.setProductList(productAddList);
                    OrderOutputAddReq addReq = new OrderOutputAddReq();
                    BeanUtils.copyProperties(res, addReq);
                    List<OrderOutputPackageAddReq> packageAddReqList = new ArrayList<>();
                    packageAddReqList.add(packageDetail);
                    addReq.setStorageId(storageId);
                    addReq.setPackageList(packageAddReqList);
                    if (storageId == 0) {
                        failOrders.add(StringsUtil.createI18Message(SysConstant.ORDER_NO_STOCK_ID, rakutenDo.getOrderNumber(), productDo.getCommoditySku()));
//                        failOrders.add("(" + productDo.getCommoditySku() + ")库存不足");
                    } else {
                        addReq.setOrderNo(addReq.getOrderNo() + (orderCount > 0 ? ("-" + orderCount) : ""));
                        orderCount++;
                        resList.add(addReq);
                    }
                    orderOutputAddReqList.addAll(resList);
                }
            }
        } catch (BizException e) {
            e.printStackTrace();
            failOrders.add(StringsUtil.createI18Message(e.getMessage(), e.getArgs()));
        }
//            Session session = mailService.initMailSession();
//            Transport transport = mailService.initMailTransport(session);
        operateRecordDao.operateAddRecord(SysConstant.OPERATE_CLICK_SEND, Long.parseLong(orderid), currentUserId, 5);
        //        List<String> failOrders = new ArrayList<>();

        for (OrderOutputAddReq outputAddReq : orderOutputAddReqList) {
            StringBuilder sku = new StringBuilder();
            int cout = 0;
            for (OrderOutputProductAddReq orderOutputProductAddReq : outputAddReq.getPackageList().get(0).getProductList()) {
                cout = cout + orderOutputProductAddReq.getCount();
                if (org.apache.commons.lang3.StringUtils.isNotBlank(sku)) {
                    sku.append(",");
                }
                sku.append(productInfoService.getById(orderOutputProductAddReq.getProductId()).getCommoditySku());
            }
            outputAddReq.setSku(sku.toString());
            outputAddReq.setCount(cout);
        }
        Map map = new HashMap();
        map.put("orderList", orderOutputAddReqList);
        map.put("failedList", failOrders);
        map.put("storageList", storageDao.selectList(null));
        return SingleResult.success(map);
    }

    @Override
    public SingleResult sendOutMatch(List<OrderOutputAddReq> orderOutputAddReqList, Long userId, Long companyId) {
        List<String> failOrders = outputService.addRakutenList(orderOutputAddReqList, userId);
        if (failOrders.size() > 0) {
            return SingleResult.failure("300", SysConstant.EXPORT_OUT_ORDER_SUCCESS_ID, failOrders, orderOutputAddReqList.size() - failOrders.size());
        } else {
            return SingleResult.success(failOrders);
        }
    }

    private void sufficientFundsCheck(Long companyId) {
        if (!companyAccountService.getIsDue(companyId)) {
            throw new NotSufficientFundsException(ErrorEnum.NOT_SUFFICIENT_FUNDS);
        }
    }

    private List<OrderOutputAddReq> sendOutOrder(OrderRakutenDo rakutenDo, boolean b) {
//        OrderRakutenDo rakutenDo = this.baseMapper.selectById(orderid);
//        if (rakutenDo == null) throw new BizExceptionI18(SysConstant.NO_ORDER_INFO_ID, rakutenDo.getOrderNumber());
        if (rakutenDo.getOrderProgress() < 300 && StringUtils.isBlank(rakutenDo.getOrderFixDatetime()))
            throw new BizExceptionI18(SysConstant.ORDER_NO_PAYMENT_ID, rakutenDo.getOrderNumber());
        List<OrderOutputAddReq> resList = new ArrayList<>();
        //订单
        OrderOutputAddReq res = new OrderOutputAddReq();
        res.setOrderType(1);
        res.setPlatform("rakuten");
        res.setPlatformNumber(rakutenDo.getId() + "");
        res.setSendDate(new Date());
        res.setShopId(rakutenDo.getShopId());
        res.setCompanyId(rakutenDo.getCompanyId());
        res.setOrderNo(rakutenDo.getOrderNumber());
        // res.setTips(rakutenDo.getRemarks());

        res.setDeliveryDate(rakutenDo.getDeliveryDate());
        if ("1".equals(rakutenDo.getShippingTerm())) {
            res.setDeliveryTime("09-12");
        } else {
            res.setDeliveryTime(rakutenDo.getShippingTerm());
        }
        res.setShipmentType(rakutenDo.getAsurakuFlag());//乐天次日达
        QueryWrapper<OrderRakutenPackageDo> wrapper = new QueryWrapper<>();
        wrapper.eq("order_id", rakutenDo.getId());
        List<OrderRakutenPackageDo> packageDoList = packageDao.selectList(wrapper);
        if (packageDoList == null || packageDoList.size() < 1)
            throw new BizExceptionI18(SysConstant.ORDER_NO_SKU_ID, rakutenDo.getOrderNumber());
//            throw new BizException(String.format("%s该订单没有SKU包裹", rakutenDo.getOrderNumber()));
        if (rakutenDo.getSomeSenderFlag() == null || rakutenDo.getSomeSenderFlag() == 0) {
            OrderRakutenPackageDo packageDo = packageDoList.get(0);//乐天默认一个包裹
            res.setReceiverName(packageDo.getOrderName());
            res.setTelPhone(packageDo.getOrderPhoneNumber());
            res.setPostCode(packageDo.getOrderPostCode());
            if (packageDo.getOrderPrefecture() != null && packageDo.getOrderPrefecture().equals("国外")) {
                throw new BizExceptionI18(SysConstant.ORDER_NO_ADDRESS_INFO2, rakutenDo.getOrderNumber(), packageDo.getOrderPrefecture());
            }
            res.setArea(packageDo.getOrderPrefecture());
            res.setAddress(packageDo.getOrderCity() + packageDo.getOrderSubAddres());
            if (packageDo.getDeliveryPrice() > 0) {
                res.setCod(rakutenDo.getRequestPrice().intValue());
            }
            if (rakutenDo.getCompanyId() == 201 || rakutenDo.getCompanyId() == 221) {
                if (packageDo.getDefaultDeliveryCompanyCode() != null)
                    if (packageDo.getDefaultDeliveryCompanyCode().equals("1001"))
                        res.setTrackId(DicBusinessItemConstant.yamatoExpress);
//                        res.setTrackId(DicBusinessItemConstant.yamatoExpressA);
                    else if (packageDo.getDefaultDeliveryCompanyCode().equals("1002"))
                        res.setTrackId(DicBusinessItemConstant.sagawaExpress);
                    else if (packageDo.getDefaultDeliveryCompanyCode().equals("1004"))
                        res.setTrackId(DicBusinessItemConstant.xinongExpress);
            }

            QueryWrapper<OrderRakutenProductDo> productDoQueryWrapper = new QueryWrapper<>();
            productDoQueryWrapper.eq("basket_id", packageDo.getBasketId());
            if (rakutenDo.getCompanyId() == 221) {
                QueryWrapper<OrderRakutenShippingDo> shippingDoQueryWrapper = new QueryWrapper<>();
                shippingDoQueryWrapper.eq("package_id", packageDo.getBasketId());
                List<OrderRakutenShippingDo> shippingDoList = shippingDao.selectList(shippingDoQueryWrapper);
                long count = shippingDoList.stream().filter(orderRakutenShippingDo -> orderRakutenShippingDo.getDeliveryCompany().equals("1004") || orderRakutenShippingDo.getDeliveryCompany().equals("1000")).count();
                if (count > 0) res.setTrackId(DicBusinessItemConstant.xinongExpress);
            }
            //得到乐天订单的产品信息集合
            List<OrderRakutenProductDo> productDoList = productDao.selectList(productDoQueryWrapper);
            List<OrderOutputProductAddReq> productDoList1 = new ArrayList<>();
            if (productDoList == null || productDoList.size() < 1)
                throw new BizExceptionI18(SysConstant.ORDER_NO_SKU_ID, rakutenDo.getOrderNumber());
//                throw new BizException(String.format("%s该订单没有SKU信息", rakutenDo.getOrderNumber()));
            for (OrderRakutenProductDo productDo : productDoList) {
                Date date = TimeUtils.parseDate(rakutenDo.getOrderDatetime(), "yyyy-MM-dd HH:mm:ss");
                productDoList1.addAll(productInfoService.getAddProductListByPlatformSku(rakutenDo.getCompanyId(), date,
                        rakutenDo.getOrderNumber(), productDo.getItemNumber(), productDo.getUnits()));
            }
//            productDoList.clear();
//            productDoList.addAll(productDoList1);
            double[] size = new double[4];
            Double shipPirce = 99999d;
            Double shipPirce2 = 99999d;
            Long storageId = 0L;
            //一单一个产品
            if (productDoList1.size() == 1 && productDoList1.get(0).getCount() == 1) {
                Long productId = getProductId(productDoList1.get(0).getCommoditySku(), rakutenDo.getCompanyId());
                if (productId == null)
                    throw new BizExceptionI18(SysConstant.ORDER_NO_SKU_INFO2_ID, rakutenDo.getOrderNumber(), productDoList1.get(0).getCommoditySku());
//                    throw new BizException(String.format("%s未找到%s信息", rakutenDo.getOrderNumber(), productDoList1.get(0).getCommoditySku()));
                size = shipPriceService.countSameSkuSize(size, productId, productDoList1.get(0).getCount());
                Long stateId = mRegionService.getStateIdByPostCode(packageDo.getOrderPostCode());
                if (stateId <= 8) {//大阪地区优先发货仓库
                    storageId = 12L;
                    if (rakutenDo.getAsurakuFlag() == 1) {
                        storageId = 10L;
                    }
                } else {//东京仓库优先发货仓库
                    storageId = 10L;
                }
                // LambdaQueryWrapper<StockRecordDo> wrapper1 = new LambdaQueryWrapper();
                // wrapper1.eq(StockRecordDo::getShopId, rakutenDo.getShopId())
                //         .eq(StockRecordDo::getProductInfoId, productId).eq(StockRecordDo::getStorageId, storageId);
                // StockRecordDo stockRecordDo = stockDao.selectOne(wrapper1);
                // int noDeliveredCount = stockDao.getOrderOutCount(productId, rakutenDo.getShopId(), storageId) + stockDao.getOrderOutTurn2FbaCount(productId, rakutenDo.getShopId(), storageId);
                int canUseCount = stockRecordService.getStockCount(rakutenDo.getCompanyId(), rakutenDo.getShopId(), storageId, productId, productDoList1.get(0).getCount());

                if (canUseCount >= productDoList1.get(0).getCount()) {//优先仓库有库存，优先仓库发货

                } else {
                    storageId = 0L;
                    long storageId1 = 0L;
                    long storageId2 = 0L;
                    QueryWrapper wrapperStorageDo = new QueryWrapper();
                    List<StorageDo> storageDos = storageDao.selectList(wrapperStorageDo);
                    for (StorageDo storageDo : storageDos) {//遍历仓库是否都有库存
                        // LambdaQueryWrapper<StockRecordDo> wrapper2 = new LambdaQueryWrapper();
                        // wrapper2.eq(StockRecordDo::getShopId, rakutenDo.getShopId()).eq(StockRecordDo::getProductInfoId, productId).eq(StockRecordDo::getStorageId, storageDo.getId());
                        // StockRecordDo stockRecordDo1 = stockDao.selectOne(wrapper2);
                        // if (stockRecordDo1 == null) continue;
                        size = shipPriceService.countSameSkuSize(new double[4], productId, productDoList1.get(0).getCount());
                        // int noDeliveredCount1 = stockDao.getOrderOutCount(productId, rakutenDo.getShopId(), storageDo.getId()) + stockDao.getOrderOutTurn2FbaCount(productId, rakutenDo.getShopId(), storageDo.getId());
                        canUseCount = stockRecordService.getStockCount(rakutenDo.getCompanyId(), rakutenDo.getShopId(), storageDo.getId(), productId, productDoList1.get(0).getCount());
                        if (canUseCount >= productDoList1.get(0).getCount()) {
                            List<ShipPriceDo> shipPriceDos = shipPriceService.queryByRegionAndSize(packageDo.getOrderPostCode(), size, res.getCod(), res.getShipmentType(), storageDo.getId(), 1, res.getCompanyId());
                            if (shipPriceDos.size() < 1 || shipPriceDos.get(0).getPrice() == 0) continue;

                            if (storageDo.getSupportShip().equals("1") || storageDo.getId() == 12L) {
                                if (shipPirce > shipPriceDos.get(0).getPrice()) {//选择次日达最便宜的价格
                                    shipPirce = shipPriceDos.get(0).getPrice();
                                    storageId1 = storageDo.getId();
                                }
                            }
                            if (shipPirce2 > shipPriceDos.get(0).getPrice()) {//选择所有最便宜的价格
                                shipPirce2 = shipPriceDos.get(0).getPrice();
                                storageId2 = storageDo.getId();
                            }
                        }
                    }
                    //乐天次日达订单有限选择次日达仓库
                    if (rakutenDo.getAsurakuFlag() == 1 && storageId1 > 0) {
                        storageId = storageId1;
                    } else {//非次日达或次日达仓库无货
                        storageId = storageId2;
                    }
                }
                List<OrderOutputProductAddReq> productAddList = new ArrayList<>();
                if (storageId == 0)
                    throw new BizExceptionI18(SysConstant.ORDER_NO_STOCK_ID, rakutenDo.getOrderNumber(), productDoList1.get(0).getCommoditySku());
//                    throw new BizException(rakutenDo.getOrderNumber() + "(" + productDoList1.get(0).getCommoditySku() + "库存不足)");
                OrderOutputProductAddReq productDetail = new OrderOutputProductAddReq();
//                productDetail.setOrderId(productDo.getOrderAmazonId());
//                productDetail.setCommoditySku(getProductId(itemsDo.getSellerSku(), orderAmazonDo.getCompanyId()));
                productDetail.setProductId(productId);
                productDetail.setCount(productDoList1.get(0).getCount());
//                productDetail.setStorageSku(null);
                productAddList.add(productDetail);
                //捆包信息
                OrderOutputPackageAddReq packageDetail = new OrderOutputPackageAddReq();
                List<OrderOutputPackageAddReq> packageAddReqList = new ArrayList<>();
                packageDetail.setProductList(productAddList);
                packageAddReqList.add(packageDetail);
                res.setStorageId(storageId);
                res.setPackageList(packageAddReqList);
                resList.add(res);
                return resList;
            } else {
                int orderCount = 0;
                Long stateId = mRegionService.getStateIdByPostCode(packageDo.getOrderPostCode());
                if (stateId <= 7) {//大阪地区优先发货仓库
                    storageId = 12L;
                    if (rakutenDo.getAsurakuFlag() == 1) {
                        storageId = 10L;
                    }
                } else if (stateId >= 8) {//东京仓库优先发货仓库
                    storageId = 10L;
                }
                List<OrderOutputProductAddReq> noStockProductList = new ArrayList<>();
                List<OrderOutputProductAddReq> productAddList = new ArrayList<>();
                for (OrderOutputProductAddReq productDo : productDoList1) {//多个产品判断
                    Long productId = productDo.getProductId();
                    if (productId == null)
                        throw new BizExceptionI18(SysConstant.ORDER_NO_SKU_INFO2_ID, rakutenDo.getOrderNumber(), productDoList1.get(0).getCommoditySku());
//                        throw new BizException(String.format("%s未找到%s信息", rakutenDo.getOrderNumber(), productDoList1.get(0).getCommoditySku()));
//                     ProductInfoDo productInfoDo = productInfoService.getById(productId);
                    // LambdaQueryWrapper<StockRecordDo> wrapper1 = new LambdaQueryWrapper();
                    // wrapper1.eq(StockRecordDo::getShopId, rakutenDo.getShopId()).eq(StockRecordDo::getProductInfoId, productId).eq(StockRecordDo::getStorageId, storageId);
                    // StockRecordDo stockRecordDo = stockDao.selectOne(wrapper1);
                    // if (stockRecordDo == null) {
                    //     noStockProductList.add(productDo);
                    //     continue;
                    // }
                    // int noDeliveredCount = stockDao.getOrderOutCount(productId, rakutenDo.getShopId(), storageId) + stockDao.getOrderOutTurn2FbaCount(productId, rakutenDo.getShopId(), storageId);
                    int canUseCount = stockRecordService.getStockCount(rakutenDo.getCompanyId(), rakutenDo.getShopId(), storageId, productId, productDo.getCount());

                    if (canUseCount < productDo.getCount()) {
                        noStockProductList.add(productDo);
                        continue;
                    }
                    OrderOutputProductAddReq productDetail = new OrderOutputProductAddReq();
                    productDetail.setProductId(productId);
                    productDetail.setCount(productDo.getCount());
                    productAddList.add(productDetail);
                }
                OrderOutputPackageAddReq packageDetail = new OrderOutputPackageAddReq();
                List<OrderOutputPackageAddReq> packageAddReqList = new ArrayList<>();
                packageDetail.setProductList(productAddList);
                OrderOutputAddReq addReq = new OrderOutputAddReq();
                BeanUtils.copyProperties(res, addReq);
                packageAddReqList.add(packageDetail);
                addReq.setStorageId(storageId);
                addReq.setPackageList(packageAddReqList);
                if (noStockProductList.size() != productDoList1.size()) {
                    resList.add(addReq);
                    orderCount += 1;
                }
                //一个仓库是否发完所有订单
                if (noStockProductList.size() > 0) {
                    if (noStockProductList.size() == 1 && noStockProductList.get(0).getCount() == 1) {
                        storageId = 0L;
                        Long productId = noStockProductList.get(0).getProductId();
                        List<StorageDo> storageDos = storageDao.selectList(null);
                        shipPirce = 99999D;
                        for (StorageDo storageDo : storageDos) {//遍历仓库是否都有库存
                            // LambdaQueryWrapper<StockRecordDo> wrapper2 = new LambdaQueryWrapper();
                            // wrapper2.eq(StockRecordDo::getShopId, rakutenDo.getShopId()).eq(StockRecordDo::getProductInfoId, productId).eq(StockRecordDo::getStorageId, storageDo.getId());
                            // StockRecordDo stockRecordDo1 = stockDao.selectOne(wrapper2);
                            // size = shipPriceService.countSameSkuSize(new double[4], productId, noStockProductList.get(0).getCount());
                            // int noDeliveredCount1 = stockDao.getOrderOutCount(productId, rakutenDo.getShopId(), storageDo.getId()) + stockDao.getOrderOutTurn2FbaCount(productId, rakutenDo.getShopId(), storageDo.getId());
                            int canUseCount = stockRecordService.getStockCount(rakutenDo.getCompanyId(), rakutenDo.getShopId(), storageDo.getId(), productId, noStockProductList.get(0).getCount());
                            if (canUseCount >= noStockProductList.get(0).getCount()) {
                                List<ShipPriceDo> shipPriceDos = shipPriceService.queryByRegionAndSize(packageDo.getOrderPostCode(), size, res.getCod(), res.getShipmentType(), storageDo.getId(), 1, res.getCompanyId());
                                if (shipPriceDos.size() < 1 || shipPriceDos.get(0).getPrice() == 0) continue;
                                if (shipPirce > shipPriceDos.get(0).getPrice()) {//选择最便宜的价格
                                    shipPirce = shipPriceDos.get(0).getPrice();
                                    storageId = storageDo.getId();
                                }
                            }
                        }

                        OrderOutputProductAddReq productDetail = new OrderOutputProductAddReq();
                        productDetail.setProductId(productId);
                        productDetail.setCount(noStockProductList.get(0).getCount());
                        List<OrderOutputProductAddReq> productAddReqLIst = new ArrayList<>();
                        productAddReqLIst.add(productDetail);
                        OrderOutputPackageAddReq packageDetail1 = new OrderOutputPackageAddReq();
                        if (storageId == 0)
                            throw new BizExceptionI18(SysConstant.ORDER_NO_STOCK_ID, rakutenDo.getOrderNumber(), noStockProductList.get(0).getCommoditySku());
//                            throw new BizException(rakutenDo.getOrderNumber() + "(" + noStockProductList.get(0).getCommoditySku() + "库存不足)");
                        List<OrderOutputPackageAddReq> packageAddReqList1 = new ArrayList<>();
                        packageDetail1.setProductList(productAddReqLIst);
                        OrderOutputAddReq addReq1 = new OrderOutputAddReq();
                        BeanUtils.copyProperties(res, addReq1);
                        packageAddReqList1.add(packageDetail1);
                        addReq1.setStorageId(storageId);
                        addReq1.setPackageList(packageAddReqList1);
                        if (orderCount > 0) addReq1.setOrderNo(addReq1.getOrderNo() + "-" + orderCount);
                        resList.add(addReq1);
                        return resList;
                    } else {
                        List<OrderOutputProductAddReq> productDoListFailed = new ArrayList<>();
                        Map<Long, List<OrderOutputProductAddReq>> productDoListMapSuccess = new HashMap<>();
                        LambdaQueryWrapper<StorageDo> lambdaQueryWrapper = new LambdaQueryWrapper();
                        lambdaQueryWrapper.eq(StorageDo::getSupportShip, 1).ne(StorageDo::getId, storageId);
                        if (stateId <= 7) {
                            lambdaQueryWrapper.orderByDesc(StorageDo::getStorageArea);
                        } else {
                            lambdaQueryWrapper.orderByAsc(StorageDo::getStorageArea);
                        }
                        List<StorageDo> storageDos = storageDao.selectList(lambdaQueryWrapper);
                        List<OrderOutputProductAddReq> productAddReqLIst = new ArrayList<>();
                        if (storageDos != null) {
                            for (StorageDo storageDo : storageDos) {
                                ;//遍历支持捆包仓库是否都有库存
                                //当前仓库是否能发所有SKU
                                for (OrderOutputProductAddReq productDo : noStockProductList) {
                                    Long productId = productDo.getProductId();
                                    // LambdaQueryWrapper<StockRecordDo> wrapper1 = new LambdaQueryWrapper();
                                    // wrapper1.eq(StockRecordDo::getShopId, rakutenDo.getShopId()).eq(StockRecordDo::getProductInfoId, productId).eq(StockRecordDo::getStorageId, storageDo.getId());
                                    // StockRecordDo stockRecordDo = stockDao.selectOne(wrapper1);
                                    // if (stockRecordDo != null) {
                                    // int noDeliveredCount = stockDao.getOrderOutCount(productId, rakutenDo.getShopId(), storageDo.getId()) + stockDao.getOrderOutTurn2FbaCount(productId, rakutenDo.getShopId(), storageDo.getId());
                                    int canUseCount = stockRecordService.getStockCount(rakutenDo.getCompanyId(), rakutenDo.getShopId(), storageDo.getId(), productId, productDo.getCount());
                                    if (canUseCount < productDo.getCount()) {
//                                        productDoListFailed.add(productDo);
                                    } else {
                                        if (productDoListMapSuccess.get(storageDo.getId()) == null) {
                                            productDoListMapSuccess.put(storageDo.getId(), new ArrayList<>());
                                        }
                                        productDoListMapSuccess.get(storageDo.getId()).add(productDo);
                                    }
                                    // }
                                }
                            }
                            int maxCount = 0;
                            for (Map.Entry<Long, List<OrderOutputProductAddReq>> longListEntry : productDoListMapSuccess.entrySet()) {
                                if (maxCount < longListEntry.getValue().size()) {
                                    maxCount = longListEntry.getValue().size();
                                    storageId = longListEntry.getKey();
                                }
                            }
                            if (storageId != 0 && productDoListMapSuccess.size() > 0 && productDoListMapSuccess.get(storageId).size() > 0) {
                                for (OrderOutputProductAddReq productDo : noStockProductList) {
                                    if (productDoListMapSuccess.get(storageId).contains(productDo)) {
                                        Long productId = productDo.getProductId();
                                        OrderOutputProductAddReq productDetail = new OrderOutputProductAddReq();
                                        productDetail.setProductId(productId);
                                        productDetail.setCount(productDo.getCount());
                                        productAddReqLIst.add(productDetail);
                                    } else {
                                        productDoListFailed.add(productDo);
                                    }
                                }
                                OrderOutputPackageAddReq packageDetail1 = new OrderOutputPackageAddReq();
                                List<OrderOutputPackageAddReq> packageAddReqList1 = new ArrayList<>();
                                packageDetail1.setProductList(productAddReqLIst);
                                addReq = new OrderOutputAddReq();
                                BeanUtils.copyProperties(res, addReq);
                                packageAddReqList1.add(packageDetail1);
                                addReq.setStorageId(storageId);
                                addReq.setPackageList(packageAddReqList1);
                                // resList.add(addReq);
                            } else {
                                productDoListFailed.addAll(noStockProductList);
                            }
                        } else {
                            productDoListFailed.addAll(noStockProductList);
                        }
                        if (productDoListFailed.size() != noStockProductList.size()) {
                            if (orderCount > 0) addReq.setOrderNo(addReq.getOrderNo() + "-" + orderCount);
                            orderCount = orderCount + 1;
                            resList.add(addReq);
                        }
                        if (productDoListFailed.size() > 0) {//捆包仓库无库存，分别发
                            LambdaQueryWrapper<StorageDo> queryWrapper = new LambdaQueryWrapper();
                            queryWrapper.eq(StorageDo::getCountryType, 1);
                            List<StorageDo> storageDoList = storageDao.selectList(queryWrapper);
                            StringBuilder stringBuilder = new StringBuilder();
                            for (OrderOutputProductAddReq productDo : productDoListFailed) {
                                storageId = 0L;
                                shipPirce = 99999D;
                                Long productId = productDo.getProductId();
                                for (StorageDo storageDo : storageDoList) {//遍历仓库是否都有库存
                                    LambdaQueryWrapper<StockRecordDo> wrapper2 = new LambdaQueryWrapper();
                                    size = shipPriceService.countSameSkuSize(new double[4], productId, 1);
                                    // wrapper2.eq(StockRecordDo::getShopId, rakutenDo.getShopId()).eq(StockRecordDo::getProductInfoId, productId).eq(StockRecordDo::getStorageId, storageDo.getId());
                                    // StockRecordDo stockRecordDo1 = stockDao.selectOne(wrapper2);
                                    // int noDeliveredCount1 = stockDao.getOrderOutCount(productId, rakutenDo.getShopId(), storageDo.getId()) + stockDao.getOrderOutTurn2FbaCount(productId, rakutenDo.getShopId(), storageDo.getId());
                                    int canUseCount = stockRecordService.getStockCount(rakutenDo.getCompanyId(), rakutenDo.getShopId(), storageDo.getId(), productId, productDo.getCount());
                                    if (canUseCount >= productDo.getCount()) {
                                        List<ShipPriceDo> shipPriceDos = shipPriceService.queryByRegionAndSize(packageDo.getOrderPostCode(), size, res.getCod(), res.getShipmentType(), storageDo.getId(), 1, res.getCompanyId());
                                        if (shipPriceDos.size() < 1 || shipPriceDos.get(0).getPrice() == 0) continue;
                                        if (shipPirce > shipPriceDos.get(0).getPrice()) {//选择最便宜的价格
                                            shipPirce = shipPriceDos.get(0).getPrice();
                                            storageId = storageDo.getId();
                                        }
                                    }
                                }

                                OrderOutputProductAddReq productDetail = new OrderOutputProductAddReq();
                                productDetail.setProductId(productId);
                                productDetail.setCount(productDo.getCount());
                                List<OrderOutputProductAddReq> productAddList1 = new ArrayList<>();
                                productAddList1.add(productDetail);
                                packageDetail = new OrderOutputPackageAddReq();

                                packageAddReqList = new ArrayList<>();
                                packageDetail.setProductList(productAddList1);
                                addReq = new OrderOutputAddReq();
                                BeanUtils.copyProperties(res, addReq);
                                packageAddReqList.add(packageDetail);
                                addReq.setStorageId(storageId);
                                addReq.setPackageList(packageAddReqList);
                                if (storageId == 0) {
                                    stringBuilder.append("(" + productDo.getCommoditySku() + ")");
                                } else {
                                    if (orderCount > 0) addReq.setOrderNo(addReq.getOrderNo() + "-" + orderCount);
                                    orderCount += 1;
                                    resList.add(addReq);
                                }
                            }
                            if (stringBuilder.length() > 0) {
                                throw new BizExceptionI18(SysConstant.ORDER_NO_STOCK_ID, rakutenDo.getOrderNumber(), stringBuilder.toString());
//                                throw new BizException(rakutenDo.getOrderNumber() + "(" + stringBuilder.toString() + "库存不足)");
                            }
                        }
                    }
                }
            }
        } else {
            //多个包裹多个地址
        }
        return resList;
    }

    private Long getProductId(String sellerSku, Long companyId) {
        QueryWrapper productWrapper = new QueryWrapper();
        productWrapper.eq("commodity_sku", sellerSku);
        productWrapper.eq("company_id", companyId);
        ProductInfoDo productInfoDo = productInfoService.getOne(productWrapper);
        if (productInfoDo == null) {
            QueryWrapper skuWrapper = new QueryWrapper();
            skuWrapper.eq("sub_sku", sellerSku);
            skuWrapper.eq("company_id", companyId);
            ProductSkuMapDo productSkuMapDo = productSkuMapDao.selectOne(skuWrapper);
            if (productSkuMapDo == null) throw new BizExceptionI18(SysConstant.NO_PRODUCT_INFO_ID, sellerSku);
//            if (productSkuMapDo == null) throw new BizException(String.format("没有找到%s的产品信息", sellerSku));
            return productSkuMapDo.getProductInfoId();
        } else {
            return productInfoDo.getId();
        }
    }

    @Override
    public int setOrderSend(Long[] orderids, Long userId) {
        int count = baseMapper.updateRakutenOrderSend(orderids);
        for (Long orderid : orderids) {
            operateRecordDao.operateAddRecord(SysConstant.OPERATE_MARK_SEND, orderid, userId, 5);
        }
        return count;
    }

//    private void operateRecord(String str, Long orderRakutenId, Long userId) {
//        OperateRecordDo operateRecordDo = new OperateRecordDo();
//        operateRecordDo.setDeleteFlag(0);
//        operateRecordDo.setThirdId(orderRakutenId);
//        operateRecordDo.setType(5);
//        operateRecordDo.setOperateBy(userId);
//        operateRecordDo.setOperateTime(new Date());
//        operateRecordDo.setContent(str);
//        operateRecordDao.insert(operateRecordDo);
//    }

    @Override
    public boolean setOrderSysTips(Long orderId, String desc, Long companyId) {
        OrderRakutenDo rakutenOrder = baseMapper.selectById(orderId);
//        if ("1".equals(type)) {
//            //预售是1
////            rakutenOrder.setShipmentType(2);
//            rakutenOrder.setSystemMemo("予約販売" + "  " + desc);
//        } else if ("2".equals(type)) {
//            //刷单是2
////            rakutenOrder.(1);
//            rakutenOrder.setSystemMemo("测评刷单" + "  " + desc);
//        } else {
//            //刷单是2
////            rakutenOrder.setIsDel(1);
//            rakutenOrder.setSystemMemo(desc);
//        }
        if (rakutenOrder == null) throw new BizExceptionI18(SysConstant.NO_ORDER_INFO);
        rakutenOrder.setSystemMemo(desc);
        updateById(rakutenOrder);
        return true;
    }

    //查询分页列表之后对列表数据的处理
    private List<OrderRakutenListRes> handlerListAfter(List<OrderRakutenDo> list) {
        List<OrderRakutenListRes> result = new ArrayList<>();
        for (OrderRakutenDo sourceDo : list) {
            OrderRakutenListRes targetDo = new OrderRakutenListRes();
            BeanUtils.copyProperties(sourceDo, targetDo);
            QueryWrapper wrapper = new QueryWrapper();
            wrapper.eq("order_id", sourceDo.getId());
            List<OrderRakutenPackageDo> packageDoList = packageDao.selectList(wrapper);
            QueryWrapper wrapper1 = new QueryWrapper();
            if (packageDoList == null || packageDoList.size() < 1) continue;
            wrapper1.eq("basket_id", packageDoList.get(0).getBasketId());
            List<OrderRakutenProductDo> productDoList = productDao.selectList(wrapper1);
            targetDo.setShipmentType(sourceDo.getAsurakuFlag());
            result.add(targetDo);
        }
        return result;
    }

    private IPage<OrderRakutenDo> pageInit(Map<String, String> map) {
        IPage<OrderRakutenDo> page = new Page();
        page.setSize(StringUtils.isNotBlank(map.get("pageSize")) ? Long.parseLong(map.get("pageSize")) : 10);
        page.setCurrent(StringUtils.isNotBlank(map.get("current")) ? Long.parseLong(map.get("current")) : 1);
        return page;
    }

    private LambdaQueryWrapper<OrderRakutenDo> queryBuild(OrderRakutenQueryBo bo) {
        LambdaQueryWrapper<OrderRakutenDo> lqw = new LambdaQueryWrapper<>();
        lqw.like(StringUtils.isNotBlank(bo.getSku()), OrderRakutenDo::getCommoditySku, bo.getSku());
        lqw.like(StringUtils.isNotBlank(bo.getOrderNumber()), OrderRakutenDo::getOrderNumber, bo.getOrderNumber());
        lqw.like(StringUtils.isNotBlank(bo.getOrderName()), OrderRakutenDo::getOrderName, bo.getOrderName());
        lqw.like(StringUtils.isNotBlank(bo.getSystemMemo()), OrderRakutenDo::getSystemMemo, bo.getSystemMemo());
        lqw.like(StringUtils.isNotBlank(bo.getOrderPhone()), OrderRakutenDo::getOrderPhoneNumber, bo.getOrderPhone());

        lqw.eq(StringUtils.isNotBlank(bo.getIsSend()), OrderRakutenDo::getIsSendOut, bo.getIsSend());
        lqw.eq(StringUtils.isNotBlank(bo.getShipmentType()), OrderRakutenDo::getAsurakuFlag, bo.getShipmentType());
        lqw.eq(StringUtils.isNotBlank(bo.getOrderProgress()), OrderRakutenDo::getOrderProgress, bo.getOrderProgress());
        lqw.eq(StringUtils.isNotBlank(bo.getShipType()), OrderRakutenDo::getAsurakuFlag, bo.getShipType());
        lqw.eq(StringUtils.isNotBlank(bo.getShopId()), OrderRakutenDo::getShopId, bo.getShopId());
        lqw.eq(Objects.nonNull(bo.getCompanyId()), OrderRakutenDo::getCompanyId, bo.getCompanyId());
        if ("1".equals(bo.getDateType())) {
            // 用户下单时间
            lqw.le(Objects.nonNull(bo.getDateEnd()), OrderRakutenDo::getOrderDatetime, bo.getDateEnd());
            lqw.ge(Objects.nonNull(bo.getDateStart()), OrderRakutenDo::getOrderDatetime, bo.getDateStart());
        } else {
            //默认用户付款时间
            lqw.ge(Objects.nonNull(bo.getDateStart()), OrderRakutenDo::getOrderFixDatetime, bo.getDateStart());
            lqw.le(Objects.nonNull(bo.getDateEnd()), OrderRakutenDo::getOrderFixDatetime, bo.getDateEnd());
        }
        lqw.orderByDesc(OrderRakutenDo::getOrderFixDatetime);
        return lqw;
    }


    /**
     * 自动同步乐天订单
     */
    @Override
    public void autoRefreshOrder() {
        List<ShopDo> shopBeans = mShopService.list();
        for (ShopDo shop : shopBeans) {
            if (shop.getRakutenSecret() != null && shop.getRakutenLicense() != null) {
                String[] orderIds =
                        getRakutenOrderIds(
                                TimeUtils.getCurrentDateFormat(-1) + "T00:00:00+0900",
                                TimeUtils.getCurrentDateFormat() + "T" + TimeUtils.getAfterTimeFormat("HH:mm:ss", 1, 0) + "+0900",
                                orderType3,
                                orderProgressComm,
                                shop.getRakutenSecret(),
                                shop.getRakutenLicense()
                        );
                getOrder(orderIds, shop);
            }
        }
    }

    /**
     * 自动确认乐天待确认订单
     */
    @Override
    public void autoConfirmOrder() {
        List<ShopDo> shopBeans = mShopService.list();
        for (ShopDo shop : shopBeans) {
            if (shop.getRakutenSecret() != null && shop.getRakutenLicense() != null) {
                String[] orderIdsUncomfirm = searchOrderUnConfirm(TimeUtils.getCurrentDateFormat(-1) + "T00:00:00+0900", TimeUtils.getCurrentDateFormat() + "T" + TimeUtils.getAfterTimeFormat("HH:mm:ss", 1, 0) + "+0900", orderType3, shop.getRakutenSecret(), shop.getRakutenLicense());
                getOrder(orderIdsUncomfirm, shop);
            }
        }
    }

    /**
     * 乐天运单号上传
     *
     * @param orderShippingModelMap
     */
    @Override
    public void updateRakutenExpressNumberByOrderIds(Map<Integer, List<OrderShippingModelRequest>> orderShippingModelMap) {
        for (Map.Entry<Integer, List<OrderShippingModelRequest>> integerListEntry : orderShippingModelMap.entrySet()) {
            ShopDo shopBean = mShopService.getShopTokenById(integerListEntry.getKey());
            if (integerListEntry.getValue().size() > 100) {
                for (int i = 0; i <= integerListEntry.getValue().size() / 100; i++) {
                    if (i == integerListEntry.getValue().size() / 100) {
                        updateOrderShipping(integerListEntry.getValue().subList(i * 100, integerListEntry.getValue().size()), shopBean.getId(), shopBean.getRakutenSecret(), shopBean.getRakutenLicense());
                    } else {
                        updateOrderShipping(integerListEntry.getValue().subList(i * 100, (i + 1) * 100), shopBean.getId(), shopBean.getRakutenSecret(), shopBean.getRakutenLicense());

                    }
                }
            } else {
                updateOrderShipping(integerListEntry.getValue(), shopBean.getId(), shopBean.getRakutenSecret(), shopBean.getRakutenLicense());
            }
        }
    }

    @Override
    public List<Map> ordersyncInit(Long currentUserId, Long companyId) {
        List<Map> shopList = new ArrayList<>();
        UserDo userDo = userDao.selectById(currentUserId);
        if (userDo == null) throw new BizExceptionI18(SysConstant.NO_USER_INFO);
        LambdaQueryWrapper<ShopDo> shopWrapper = new LambdaQueryWrapper();
        if (userDo.getShopId() != null) shopWrapper.eq(ShopDo::getId, userDo.getShopId());
        shopWrapper.eq(ShopDo::getCompanyId, companyId);
        shopWrapper.isNotNull(ShopDo::getRakutenLicense);
        shopWrapper.isNotNull(ShopDo::getRakutenSecret);
        List<ShopDo> shopDoList = shopDao.selectList(shopWrapper);
        if (!CollectionUtils.isEmpty(shopDoList)) {
            for (ShopDo shopDo : shopDoList) {
                Map shopMap = new HashMap();
                shopMap.put("id", shopDo.getId());
                shopMap.put("value", shopDo.getShopName());
                shopList.add(shopMap);
            }
        }
        return shopList;
    }

    @Override
    public void tset1() {
        List<OrderRakutenProductDo> productDoList = rakutenProductService.list();
        for (OrderRakutenProductDo productDo : productDoList) {
            try {
                productDo.setProductInfoId(getProductId1(productDo.getItemNumber()));
                productDao.updateById(productDo);
            } catch (Exception e) {
                e.printStackTrace();
            }

        }
    }

    private Long getProductId1(String sellerSku) {
        QueryWrapper productWrapper = new QueryWrapper();
        productWrapper.eq("commodity_sku", sellerSku);
        ProductInfoDo productInfoDo = productInfoService.getOne(productWrapper);
        if (productInfoDo == null) {
            QueryWrapper skuWrapper = new QueryWrapper();
            skuWrapper.eq("sub_sku", sellerSku);
            ProductSkuMapDo productSkuMapDo = productSkuMapDao.selectOne(skuWrapper);
            if (productSkuMapDo == null) throw new BizExceptionI18(SysConstant.NO_PRODUCT_INFO_ID, sellerSku);
            return productSkuMapDo.getProductInfoId();
        } else {
            return productInfoDo.getId();
        }
    }

    @Override
    public SingleResult updateOrderSender(OrderSenderUpdateReq req) {
        OrderRakutenPackageDo orderRakutenPackageDo = packageDao.selectById(req.getBasketId());
        OrderRakutenDo orderRakutenDo = dao.selectById(orderRakutenPackageDo.getOrderId());
        if (orderRakutenDo == null) throw new BizExceptionI18(SysConstant.NO_ORDER_INFO);
        ShopDo shop = shopDao.selectById(orderRakutenDo.getShopId());
        if (orderRakutenPackageDo == null) throw new BizExceptionI18(SysConstant.NO_ORDER_INFO);
        LambdaQueryWrapper<OrderRakutenProductDo> productDoLambdaQueryWrapper = new LambdaQueryWrapper<>();
        productDoLambdaQueryWrapper.eq(OrderRakutenProductDo::getBasketId, req.getBasketId());
        List<OrderRakutenProductDo> orderRakutenProductDoList = productDao.selectList(productDoLambdaQueryWrapper);
        for (OrderRakutenProductDo productDo : orderRakutenProductDoList) {
            for (OrderRakutenProductResponse orderRakutenProductResponse : req.getProductResponseList()) {
                if (orderRakutenProductResponse.getItemDetailId().longValue() == productDo.getItemDetailId().longValue()) {
                    orderRakutenProductResponse.setIncludeTaxFlag(productDo.getIncludeTaxFlag());
                    orderRakutenProductResponse.setIncludePostageFlag(productDo.getIncludePostageFlag());
                    orderRakutenProductResponse.setIncludeCashOnDeliveryPostageFlag(productDo.getIncludeCashOnDeliveryPostageFlag());
                    BeanUtils.copyProperties(orderRakutenProductResponse, productDo);
                    productDao.updateById(productDo);
                }
            }
        }
        BeanUtils.copyProperties(req, orderRakutenPackageDo);
        packageDao.updateById(orderRakutenPackageDo);
        //构造请求参数
        Map requestMap = new HashMap();
        requestMap.put("orderNumber", orderRakutenDo.getOrderNumber());
        requestMap.put("reductionReason", 10);
        List<OrderSenderUpdateReq> reqList = new ArrayList<>();
        SenderModelEntity senderModelEntity = new SenderModelEntity();
        String zipCode = req.getOrderPostCode().replace("-", "");
        senderModelEntity.setZipCode1(zipCode.substring(0, 3));
        senderModelEntity.setZipCode2(zipCode.substring(3));
        senderModelEntity.setPrefecture(req.getOrderPrefecture());
        senderModelEntity.setCity(req.getOrderCity());
        senderModelEntity.setSubAddress(req.getOrderSubAddres());
        senderModelEntity.setFamilyName(req.getOrderName());
        senderModelEntity.setFirstName(" ");
        String phone = req.getOrderPhoneNumber().replaceAll("-", "");
        senderModelEntity.setPhoneNumber1(phone.substring(0, 3));
        senderModelEntity.setPhoneNumber2(phone.substring(3, 7));
        senderModelEntity.setPhoneNumber3(phone.substring(7));
        req.setSenderModel(senderModelEntity);
//        req.setProductResponseList(null);
        reqList.add(req);
        requestMap.put("PackageModelList", reqList);

        //保存到乐天服务器
        String requestBody = JSON.toJSONString(requestMap);
        logger.debug(requestBody);
        String authorization = "ESA " + Base64.getEncoder().encodeToString((shop.getRakutenSecret() + ":" + shop.getRakutenLicense()).getBytes());
//        String jsonData = OkHttpUtils.okHttpRequest(GlobalConstants.RakutenURL + "/order/updateOrderSender/",
//                HttpMethod.POST.name(), requestBody, authorization);
//        JSONObject orderBody = JSON.parseObject(jsonData);
//        if ("ORDER_EXT_API_UPDATE_ORDERSENDER_INFO_101".equals(orderBody.getJSONArray("MessageModelList").getJSONObject(0).getString("messageCode"))) {
//
//        } else {
//            throw new BizException(orderBody.getJSONArray("MessageModelList").getJSONObject(0).getString("message"));
//        }
        return SingleResult.failure("cuowu");
    }

    /**
     * order/updateOrderOrderer/
     *
     * @param req
     * @return
     */
    @Override
    public SingleResult updateOrderBaseInfo(OrderBaseInfoUpdateReq req) {
        OrderRakutenDo orderRakutenDo = dao.selectById(req.getId());
        if (orderRakutenDo == null) throw new BizExceptionI18(SysConstant.NO_ORDER_INFO);
        ShopDo shop = shopDao.selectById(orderRakutenDo.getShopId());

        //构造请求参数(订购人信息)
        Map requestMap = new HashMap();
        SenderModelEntity senderModelEntity = new SenderModelEntity();
        String zipCode = orderRakutenDo.getOrderPostCode().replace("-", "");
        senderModelEntity.setZipCode1(zipCode.substring(0, 3));
        senderModelEntity.setZipCode2(zipCode.substring(3));
        senderModelEntity.setPrefecture(orderRakutenDo.getOrderPrefecture());
        senderModelEntity.setCity(orderRakutenDo.getOrderCity());
        senderModelEntity.setSubAddress(req.getOrderSubAddres());
        senderModelEntity.setFamilyName(req.getOrderName());
        senderModelEntity.setFirstName(" ");
        String phone = req.getOrderPhoneNumber().replaceAll("-", "");
        senderModelEntity.setPhoneNumber1(phone.substring(0, 3));
        senderModelEntity.setPhoneNumber2(phone.substring(3, 7));
        senderModelEntity.setPhoneNumber3(phone.substring(7));
        requestMap.put("orderNumber", orderRakutenDo.getOrderNumber());
        requestMap.put("OrdererModel", senderModelEntity);
        //保存到乐天服务器
        String requestBody = JSON.toJSONString(requestMap);
        logger.debug(requestBody);
        String authorization = "ESA " + Base64.getEncoder().encodeToString((shop.getRakutenSecret() + ":" + shop.getRakutenLicense()).getBytes());
//        String orderResponse = OkHttpUtils.okHttpRequest(GlobalConstants.RakutenURL + "/order/updateOrderOrderer/",
//                HttpMethod.POST.name(), requestBody, authorization);
//        JSONObject orderBody = JSON.parseObject(orderResponse);
//        if ("ORDER_EXT_API_UPDATE_ORDERORDERER_INFO_101".equals(orderBody.getJSONArray("MessageModelList").getJSONObject(0).getString("messageCode"))) {
//
//        } else {
//            throw new BizException(orderBody.getJSONArray("MessageModelList").getJSONObject(0).getString("message"));
//        }
        int shippingNumber;
        requestMap = new HashMap();
        requestMap.put("orderNumber", orderRakutenDo.getOrderNumber());
        requestMap.put("deliveryDate", req.getDeliveryDate());
        if (StringUtils.isBlank(req.getShippingTerm()) || req.getShippingTerm().equals("-")) {
            shippingNumber = 0;
        } else if (req.getShippingTerm().equals("09-12") || req.getShippingTerm().equals("08-12")) {
            shippingNumber = 1;
        } else {
            shippingNumber = Integer.parseInt(req.getShippingTerm().replaceAll("-", ""));
        }
        requestMap.put("shippingTerm", shippingNumber);
//        requestMap.put("memo",req.getSystemMemo());
        //保存到乐天服务器
        requestBody = JSON.toJSONString(requestMap);
        logger.debug(requestBody);
//        String memoResponse = OkHttpUtils.okHttpRequest(GlobalConstants.RakutenURL + "/order/updateOrderMemo/",
//                HttpMethod.POST.name(), requestBody, authorization);
//        JSONObject memoBody = JSON.parseObject(memoResponse);
//        if ("ORDER_EXT_API_UPDATE_ORDERMEMO_INFO_101".equals(memoBody.getJSONArray("MessageModelList").getJSONObject(0).getString("messageCode"))) {
//
//        } else {
//            throw new BizException(memoBody.getJSONArray("MessageModelList").getJSONObject(0).getString("message"));
//        }
        BeanUtils.copyProperties(req, orderRakutenDo);
        dao.updateById(orderRakutenDo);
        return SingleResult.success();
    }

    @Override
    public List<String> expire(Long companyId) {
        List<String> strings = new ArrayList<>();
        List<ShopDo> shopDoList = shopDao.selectList(new LambdaQueryWrapper<ShopDo>().eq(ShopDo::getCompanyId, companyId));
        for (ShopDo shopDo : shopDoList) {
            if (StringUtils.isNotBlank(shopDo.getRakutenLicense()) && shopDo.getExpirationTime() != null) {
                long days = (shopDo.getExpirationTime().getTime() - System.currentTimeMillis()) / (24 * 60 * 60 * 1000);
                if (days < 0) {
                    strings.add(String.format("%s的店铺授权已过期，请及时更新秘钥", shopDo.getShopName(), days));
                } else if (days < 7) {
                    strings.add(String.format("%s的店铺授权在%d天后将过期，请及时更新秘钥", shopDo.getShopName(), days));
                }
            }
        }
        return strings;
    }

    @Override
    public void autoSendRakutenOrder() {
        Calendar calendar = Calendar.getInstance();
        int i = calendar.get(Calendar.HOUR_OF_DAY);
        List<OrderRakutenDo> orderRakutenDos = dao.selectList(new LambdaQueryWrapper<OrderRakutenDo>().eq(OrderRakutenDo::getOrderProgress, 300)
                .eq(OrderRakutenDo::getIsSendOut, 0)
                .ge(OrderRakutenDo::getOrderFixDatetime, TimeUtils.getCurrentDateFormat(-3))
                .eq(OrderRakutenDo::getCompanyId, 201));
        if (orderRakutenDos.size() >= 300 || i == 11) {
            List<String> collect = orderRakutenDos.stream().map(rakutenDo -> rakutenDo.getId() + "").collect(Collectors.toList());
            queryOrder2SendOut(collect.toArray(new String[collect.size()]), 1L, true, 201L);
        }
        // queryOrder2SendOut(collect.toArray(new String[collect.size()]), 1L, true, 201L);
    }

    @Override
    public void autoSendRakutenOrder2() {
        List<Long> companyIds = new ArrayList<>();
        companyIds.add(636L);
        companyIds.add(404L);
        for (Long companyId : companyIds) {
            List<OrderRakutenDo> orderRakutenDos = dao.selectList(new LambdaQueryWrapper<OrderRakutenDo>().eq(OrderRakutenDo::getOrderProgress, 300)
                    .eq(OrderRakutenDo::getIsSendOut, 0)
                    .ge(OrderRakutenDo::getOrderFixDatetime, TimeUtils.getCurrentDateFormat(-30))
                    .eq(OrderRakutenDo::getCompanyId, companyId));
            if (orderRakutenDos.isEmpty()) continue;
            List<String> collect = orderRakutenDos.stream().map(rakutenDo -> rakutenDo.getId() + "").collect(Collectors.toList());
            if (collect.isEmpty()) continue;
            queryOrder2SendOut(collect.toArray(new String[collect.size()]), 1L, true, companyId);
        }

        // queryOrder2SendOut(collect.toArray(new String[collect.size()]), 1L, true, 201L);
    }

    @Override
    public void updateOrderSendOut(String orderNo) {
        dao.updateOrderSendOut(orderNo);
    }

    private List<OrderOutputAddReq> sendOutOrder2(String orderid, boolean b) {
        //根据传过来的订单  查看产品 对比拥有此产品的仓库单个产品的价格  然后合理分配 存在多种情
        // eg:产品从一个仓库出；产品从两个或多个仓库出  算出运费最低的情况处理
        //得到乐天的订单信息
        OrderRakutenDo rakutenDo = this.baseMapper.selectById(orderid);
        if (rakutenDo == null) throw new BizExceptionI18(SysConstant.NO_ORDER_INFO_ID, rakutenDo.getOrderNumber());
        //判断未处理订单是要在300  且 需要有顾客的付款时间
        if (rakutenDo.getOrderProgress() < 300 && StringUtils.isBlank(rakutenDo.getOrderFixDatetime()))
            throw new BizExceptionI18(SysConstant.ORDER_NO_PAYMENT_ID, rakutenDo.getOrderNumber());
        List<OrderOutputAddReq> resList = new ArrayList<>();
        //订单 将乐天订单信息放到定义的对象中
        OrderOutputAddReq res = new OrderOutputAddReq();
        res.setOrderType(1);
        res.setSendDate(new Date());
        res.setShopId(rakutenDo.getShopId());
        res.setCompanyId(rakutenDo.getCompanyId());
        res.setOrderNo(rakutenDo.getOrderNumber());
        res.setTips(rakutenDo.getRemarks());

        res.setDeliveryDate(rakutenDo.getDeliveryDate());
        if ("1".equals(rakutenDo.getShippingTerm())) {
            res.setDeliveryTime("09-12");
        } else {
            res.setDeliveryTime(rakutenDo.getShippingTerm());
        }
        res.setShipmentType(rakutenDo.getAsurakuFlag());//乐天次日达
        QueryWrapper<OrderRakutenPackageDo> wrapper = new QueryWrapper<>();
        wrapper.eq("order_id", orderid);
        List<OrderRakutenPackageDo> packageDoList = packageDao.selectList(wrapper);
        if (packageDoList == null || packageDoList.size() < 1)
            throw new BizExceptionI18(SysConstant.ORDER_NO_SKU_ID, rakutenDo.getOrderNumber());
        if (rakutenDo.getSomeSenderFlag() == null || rakutenDo.getSomeSenderFlag() == 0) {
            OrderRakutenPackageDo packageDo = packageDoList.get(0);//乐天默认一个包裹
            res.setReceiverName(packageDo.getOrderName());
            res.setTelPhone(packageDo.getOrderPhoneNumber());
            res.setPostCode(packageDo.getOrderPostCode());
            res.setArea(packageDo.getOrderPrefecture());
            res.setAddress(packageDo.getOrderCity() + packageDo.getOrderSubAddres());
            res.setCod(res.getCod());
            QueryWrapper<OrderRakutenProductDo> productDoQueryWrapper = new QueryWrapper<>();
            productDoQueryWrapper.eq("basket_id", packageDo.getBasketId());
            //得到乐天订单的产品信息集合
            if (rakutenDo.getCompanyId() == 201) {
                if (packageDo.getDefaultDeliveryCompanyCode() != null)
                    if (packageDo.getDefaultDeliveryCompanyCode().equals("1001"))
//                        res.setTrackId(DicBusinessItemConstant.yamatoExpressA);
                        res.setTrackId(DicBusinessItemConstant.yamatoExpress);
                    else res.setTrackId(DicBusinessItemConstant.sagawaExpress);
            }
            List<OrderRakutenProductDo> productDoList = productDao.selectList(productDoQueryWrapper);
            List<OrderRakutenProductDo> productDoList1 = new ArrayList<>();
            if (productDoList == null || productDoList.size() < 1)
                throw new BizExceptionI18(SysConstant.ORDER_NO_SKU_ID, rakutenDo.getOrderNumber());
            for (OrderRakutenProductDo productDo : productDoList) {
                if (productDo.getItemNumber().contains("+")) {
                    OrderRakutenProductDo productDo1 = new OrderRakutenProductDo();
                    BeanUtils.copyProperties(productDo, productDo1);
                    productDo1.setItemNumber(productDo.getItemNumber().split("\\+")[1]);
                    productDo.setItemNumber(productDo.getItemNumber().split("\\+")[0]);
                    productDoList1.add(productDo1);
                }
            }
            //将处理好的结果封装到list中
            productDoList.addAll(productDoList1);
            Map<Long, List<Map<Long, Integer>>> productAndStorageMap = new HashMap<>();
            List<Map<Long, List<Map<Long, Integer>>>> productAndStorageList = new ArrayList<>();
            //得到商品id和需要发送的数量
            Map<Long, Integer> products = productDoList.stream().collect(Collectors.toMap(OrderRakutenProductDo::getProductInfoId, OrderRakutenProductDo::getUnits));
            LambdaQueryWrapper<StorageDo> storageDoLambdaQueryWrapper = new LambdaQueryWrapper<>();
            storageDoLambdaQueryWrapper.eq(StorageDo::getCountryType, 1);
            List<StorageDo> storageS = storageDao.selectList(storageDoLambdaQueryWrapper);
            //得到当前仓中  是否有此商品
            List<AutoSwitchStorageEntity> storageEntityList = new ArrayList<>();
            List<List<AutoSwitchStorageEntity>> addReqEntityList = new ArrayList<>();
            for (StorageDo storageDo : storageS) {
                List<AutoSwitchStorageEntity.ProductAndCount> productAndCountList = new ArrayList<>();
                for (Long productId : products.keySet()) {
                    int count = stockRecordService.getStockCount(rakutenDo.getCompanyId(), rakutenDo.getShopId(), storageDo.getId(), productId, products.get(productId));
                    if (count < 1) {
                        continue;
                    } else if (count < products.get(productId)) {
                        productAndCountList.add(new AutoSwitchStorageEntity.ProductAndCount(productId, count));
                    } else {
                        productAndCountList.add(new AutoSwitchStorageEntity.ProductAndCount(productId, products.get(productId)));
                    }
                }
                storageEntityList.add(new AutoSwitchStorageEntity(storageDo.getId(), 0, productAndCountList));
            }
            for (AutoSwitchStorageEntity autoSwitchStorageEntity : storageEntityList) {
                int leftCount = 0;
                for (Long productId : products.keySet()) {
                    for (AutoSwitchStorageEntity.ProductAndCount productAndCount : autoSwitchStorageEntity.getProductAndCountList()) {
                        if (productId.equals(productAndCount.getProductId())) {
                            if (products.get(productId) - productAndCount.getCount() > 0) {
                                leftCount = +products.get(productId) - productAndCount.getCount();
                            }
                        }
                    }
                }
                if (leftCount < 0) {
                    break;
                }
            }

        }
        return null;
    }


}